Leetcode刷题笔记1.两数之和

原题

给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那 两个 整数,并返回他们的数组下标。

你可以假设每种输入只会对应一个答案。但是,你不能重复利用这个数组中同样的元素。

示例:

给定 nums = [2, 7, 11, 15], target = 9

因为 nums[0] + nums[1] = 2 + 7 = 9
所以返回 [0, 1]

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/two-sum

一.两数之和

1. 最初想法

直接暴力求解

class Solution {
public:
    vector<int> twoSum(vector<int>& nums, int target) {
        vector<int> vec;
        for (decltype(nums.size()) i = 0; i < nums.size(); ++i) {
            for (decltype(i) j = i + 1; j < nums.size(); ++j) {
                if ((nums[i] + nums[j]) == target) {
                    vec.emplace_back(i);
                    vec.emplace_back(j);
                    return vec;
                }
            }
        }
        return vec;
    }
};

暴力不一定是最慢的,但是最慢的暴力应该可占一席!

时间复杂度:O(n2)

空间复杂度:O(1)

2. 参考后解法

哈希表(unordered_map

我们知道map有两个键值对,我们第一遍把nums的索引及内容放unordered_map里面,第二次遍历的时候从unordered_map里面找是否有满足条件的内容,如有,保存索引即可!

抛出一种错误解法

class Solution {
public:
  vector<int> twoSum(vector<int> &nums, int target) {
    unordered_map<int, int> mp;
    int size = nums.size();
    for (int i = 0; i < size; ++i) {
      mp[nums[i]] = i;
    }
    for (int i = 0; i < size; ++i) {
      int temp = target - nums[i];
      if (mp.count(temp) == 1) {
        return {mp[temp], i};
      }
    }
    return {};
  }
};

示例:

输入:[3,2,4]
6

输出:[0,0]

预期:[1,2]

错误原因

当循环遍历到i = 0时,temp = 3,正好unordered_map里有这个3,索引为0,直接返回

这不是我们期望看到了!

当然,这也不是题目所允许的!

你可以假设每种输入只会对应一个答案。但是,你不能重复利用这个数组中同样的元素。

解决办法

保证每次取得i,j不相等即可!

class Solution {
public:
  vector<int> twoSum(vector<int> &nums, int target) {
    unordered_map<int, int> mp;
    int size = nums.size();
    for (int i = 0; i < size; ++i) {
      mp[nums[i]] = i;
    }
    for (int i = 0; i < size; ++i) {
      int temp = target - nums[i];
      if (mp.count(temp) == 1 && mp[temp] != i) {
        return {mp[temp], i};
      }
    }
    return {};
  }
};

时间复杂度:O(n)

空间复杂度:O(n)

3. 再次优化

事实上,我们可以插入查找同时进行!

class Solution {
public:
  vector twoSum(vector &nums, int target) {
    unordered_map mp;
    int size = nums.size();
    for (int i = 0; i < size; ++i) {
      int temp = target - nums[i];
      if (mp.count(temp) == 1 && mp[temp] != i) {
        return {mp[temp], i};
      }
      mp[nums[i]] = i;
    }
    return {};
  }
};

时间复杂度:O(n)

空间复杂度:O(n)

二. 总结

此题比较简单,如果用暴力解法AC完便草草了事,显然是不够的。

笔者认为此题可以当作哈希入门题,以此大致了解哈希的用途!

进阶:

15. 三数之和

诗情画意

望岳
杜甫
岱宗夫如何?齐鲁青未了。
造化钟神秀,阴阳割昏晓。
荡胸生层云,决眦入归鸟。
会当凌绝顶,一览众山小。

你可能感兴趣的:(#,算法)