Leetcode #1 Two Sum

Leetcode #1 Two Sum

  1. 题目大意
    给定一个整数数组(Integers Array),让你找出两个数 使得他们的和正好等于给定的值(Target),返回这两个数的下标。保证只有唯一解

  2. 题目分析
    这个题目题意清晰,要注意两点:

    • 返回下标,而不是数字本身,且下标是升序的。
    • 只有唯一解(这给我们带来了很大便利)
  3. 解法

    1. 我们很直接就能想到暴力解法(Brutal Force)
      利用二维循环,去扫描每一个数,找到的即为答案,注意这种办法在解不唯一且要 输出所以解的时候也适用。很显然,这个暴力算法的

      • 时间复杂度(Time Complexity)是 O(n2)
      • 空间复杂度是(Space Complexity) 是 O(1) ,因为算法运行并没有利用额外的空间

      伪代码如下:

         for(i=0;i<ArrayLen;i++)
         for(j=0;j<ArrayLen;j++)
         {
             if(Array[i] + Array[j] == Target)
             {
                 //return i,j
             }
         }
      
    2. 利用Hashmap 将我们有什么数存下来,当遇到一个数的时候,直接去存的地方看看它配对的那个数(Target - CurrentNumber)以前出现过没有,如果出现过,则找到了答案,否则将这个数也加入hashmap,继续往下找。不过Hashmap实现的时候不同语言就有不同的办法了。

      1. Python
        Python 的内建类型set 和dict是利用hash 实现的 所以查找的复杂度为 O(1) .
        而list 的查找并不是基于has key,所以复杂度近似为 O(n) ,并不能提高算法效率。

      2. C++
        利用 map即可

      3. C
        以上两种语言(还有java等等)都是利用自带或者库里的方法直接实现hash,可是对于C语言来说,hash 就需要自己实现了。

        • 首先,我们需要确定hash key对于一个数字value如何在 O(1) 时间内确定它在table里的位置。这里需要一个map functon即
          F(value)=index
        • 最简单的映射函数就是用value 直接作为下标,为了节省些许空间和处理负数,可以对坐标作关于最小值的线性变换
        • 通常映射函数是 f(value)=valuemodn n通常选一个质数来减少冲突。当冲突发生了,可以采用open(把它往后面空的地方丢)、close(下拉一个链表存所有下标一样但值不一样的数) 或者用双hash表。在此不再赘述

    4.代码

     def twoSum(self, nums, target):
        NumHash = {}
        for index, cur_num in enumerate(nums):
            need_num = target - cur_num
            if need_num in NumHash:
                return [NumHash[need_num], index]
            else:
                NumHash[need_num] = index

    未来有机会补上C和C++ 代码

    5.总结思考

    首先如果解不唯一,需要输出所有解或者最小的解(下标之和),还有没有 O(n) 的办法,该怎么写呢。
    可以尝试用C 实现hash,来理解几种冲突的解决办法

猜你喜欢

转载自blog.csdn.net/weixin_39672172/article/details/78963279