力扣基础题- 两数之和

两数之和

题目描述

题目链接:https://leetcode-cn.com/problems/two-sum

难度:简单

给定一个整数数组 nums 和一个整数目标值 target,请你在该数组中找出 和为目标值 target  的那 两个 整数,并返回它们的数组下标。
你可以假设每种输入只会对应一个答案。但是,数组中同一个元素在答案里不能重复出现。
你可以按任意顺序返回答案。

解析:

  • 最简单的方法就是暴力枚举,两重循环,第一个循环选择第\(i\)个数,第二个for循环寻找是否存在数j,使得\(i+j\)等于target,找到则输出对应下标,但该方法时间复杂度过高,且较为简单,故不提供代码(我也没写)
  • 方法二:由于我们已知target,因此对于数i,我们只需要查询\(target - i\)是否存在即可,因此可以将给定的数组排序后使用二分查找替换方法一中的第二个for循环,但是这种方法比较麻烦,因为排序时需要保证数字对应下标也跟着排序,需要使用pair。
  • 方法三:也是我是用的方法,直接开一个map,键为数字,值为下标。同方法二,对于数i,直接去map中查找\(target - i\)是否存在,若存在,则从map中取出其下标。当然,如果将map替换成自己手写的哈希表效率和内存方面应该会更佳优秀。
  • 注:若数据范围较小,可以开一个桶,极致的空间换时间,但是本题数据范围过大。

代码(方法三):

class Solution {
public:
    vector<int> twoSum(vector<int> &nums, int target) {
        map<int, int> pos = map<int, int>();  // 用于映射数字到下标的 map
        vector<int> res = vector<int>();  // 返回结果

        for (int i = 0; i < nums.size(); i++) {
            pos[nums[i]] = i;  // 增加映射
        }

        for (int i = 0; i < nums.size(); i++) {
            map<int, int>::iterator iter = pos.find(target - nums[i]);  // 查询
            if (iter != pos.end() && iter->second != i) {  // 找到答案
                res.push_back(i);
                res.push_back(iter->second);
                break;
            }
        }
        return res;  // 返回结果
    }
};

总结

接下来大部分都是废话了:这道题确实是比较基础的题目,但也考察了一些常用容器的用法。至于为什么会写这道题的题解呢,是因为最近才开始玩力扣,就像打算法时的入门题A + B一样,算是一种纪念性的意义了。

posted @ 2022-01-18 13:43  XBCoder  阅读(44)  评论(0)    收藏  举报