Leetcode01—Two Sum【两数和】

问题:

给定一个整数数组和一个目标值,返回两个数的索引,使这两个数的和为目标值。

假设每个输入只有一个解决方案,并且一个元素不能使用两次。

例子:

给定数组 nums = [2, 7, 11, 15],目标 target = 9,由于nums[0] + nums[1] = 2 + 7 = 9,所以返回[0, 1].

思路:

思路1:暴力破解

这种方法比较简单,遍历每个元素nums[i],然后查找在数组中是否存在另一个元素的值为target-nums[i],找到就返回两个数字,这个方法的时间复杂度比较大为O\left ( n^{2} \right ),空间复杂度O\left ( 1 \right )

思路2:哈希表

为了提高时间复杂度,需要用空间来换,我们需要一种更有效的方法来检查数组中是否存在target−nums[i]。 如果存在,我们需要查找其索引。 维护数组中每个元素到其索引的映射的最佳方法是什么? 哈希表。

我们通过交换空间来缩短从O(n)到O(1)的查找时间。 哈希表就是为此目的而构建的,它支持在接近恒定的时间内快速查找。 我说“接近”因为如果发生碰撞,查找可能会退化为O(n)时间。 但是只要仔细选择哈希函数,查找哈希表就应该为O(1)时间。

一个简单的实现使用两次迭代。 在第一次迭代中,我们将每个元素的值及其索引添加到表中。 然后,在第二次迭代中,我们检查表中是否存在每个元素的补码(target-nums [i])。 请注意,补充不能是nums [i] 本身!

我们只想用线性的时间复杂度来解决问题,那么就是说只能遍历一个数字,那么另一个数字呢,我们可以事先将其存储起来,使用一个HashMap,来建立数字和其坐标位置之间的映射,我们都知道HashMap是常数级的查找效率,这样,我们在遍历数组的时候,用target减去遍历到的数字,就是另一个需要的数字了,直接在HashMap中查找其是否存在即可,注意要判断查找到的数字不是第一个数字,比如target是4,遍历到了一个2,那么另外一个2不能是之前那个2,整个实现步骤为:先遍历一遍数组,建立HashMap映射,然后再遍历一遍,开始查找,找到则记录index。

C++代码:

class Solution {
public:
    vector<int> twoSum(vector<int>& nums, int target) {
    //这是一个函数 形式是 :返回值 函数名(参数表){函数体} 
    //其中返回值是vector<int>,是个 vector;
    //函数名是twoSum;
    //参数表显示要两个参数:第一个参数是vector<int> &nums(这个参数的类型是vector<int>,传参的方 
    //式是引用)。第二个参数是 int target(这个参数的类型是int,传参的方式是传值);
        for(int i = 0; i < nums.size(); i++) {
            for(int j = 0; j < nums.size(); j++) {
                if (nums[i] + nums[j] == target && i!=j) {
                    return vector<int> {i, j};
                }
            }
        }
        return vector<int>();
    } 
};
class Solution {
public:
    vector<int> twoSum(vector<int>& nums, int target) {
        unordered_map<int, int> m;//unordered_map存储的key-value的值,其中元素是无序的,
                                  //通过键的hash值将元素放置到各个桶中,这样就能够通过主键快速的 
                                  //访问各个对应的元素

        for (int i = 0; i < nums.size(); ++i) {
            m[nums[i]] = i;
        }
        for (int i = 0; i < nums.size(); ++i) {
            int t = target - nums[i];
            if (m.count(t) && m[t] != i) {//count函数,其功能类似于find,返回这个值出现次数的 
                                          //统计结果
                return vector<int> {i, m[t]};
                break;
            }
        }
        return vector<int>();
    }
};

测试: 

 

猜你喜欢

转载自blog.csdn.net/weixin_42702666/article/details/87906927