leetcode-ac
  • 玩转力扣 | 题解主页
  • leetcode1 两数之和【简单难度】
  • leetcode4 寻找两个正序数组的中位数【困难难度】
  • leetcode11 盛最多水的容器【中等难度】
  • leetcode36 有效的数独【中等难度】
  • leetcode38 外观数列(报数)【中等难度】
由 GitBook 提供支持
在本页
  • 1. 两数之和
  • 英文题目: 2 sum (Two sum)
  • 分析:
  • 方法2 AC代码:
  • 方法3 AC代码:
  • 方法3的另一种写法:
  • 方法4 AC代码:

这有帮助吗?

leetcode1 两数之和【简单难度】

上一页玩转力扣 | 题解主页下一页leetcode4 寻找两个正序数组的中位数【困难难度】

最后更新于3年前

这有帮助吗?

● 难度:

简单

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

你可以假设每种输入只会对应一个答案。但是,数组中同一个元素在答案里不能重复出现。

你可以按任意顺序返回答案。

示例 1:

输入:nums = [2,7,11,15], target = 9
输出:[0,1]
解释:因为 nums[0] + nums[1] == 9 ,返回 [0, 1] 。

示例 2:

输入:nums = [3,2,4], target = 6
输出:[1,2]

示例 3:

输入:nums = [3,3], target = 6
输出:[0,1]

提示:

  • 2 <= nums.length <= 104

  • -109 <= nums[i] <= 109

  • -109 <= target <= 109

  • 只会存在一个有效答案

进阶: 你可以想出一个时间复杂度小于 O(n2) 的算法吗?

英文题目: 2 sum (Two sum)

Given an array of integers nums and an integer target, return indices of the two numbers such that they add up to target. You may assume that each input would have **_exactly one solution**, and you may not use the same element twice. You can return the answer in any order.

Example 1:

Input: nums = [2,7,11,15], target = 9 Output: [0,1]

Explaination: Because nums[0] + nums[1] == 9, we return [0, 1].

Example 2: Input: nums = [3,2,4], target = 6 Output: [1,2]

Example 3: Input: nums = [3,3], target = 6 Output: [0,1]

Constraints:

  • 2 <= nums.length <= 103

  • -109 <= nums[i] <= 109

  • -109 <= target <= 109

  • Only one valid answer exists.

分析:

方法1: 暴力法,复杂度O(n^2),会TLE(超时).

方法2: 双指针法, 固定一个, 找另一个. 发现第一次出现nums[i] + nums[j] == target就返回结果.

方法3: hashmap查表,在表中找 target - 当前循环变量i对应的那个数。用一个哈希表(C++中用unordered_map, C#中用dictionary, Python中用dict,Java中可以直接用HashMap),存储每个数对应的下标,复杂度O(n);

方法4: 快排 + 双指针

方法2 AC代码:

class Solution {
public:
    vector<int> twoSum(vector<int>& nums, int target) {        
        vector<int> res(2);
        // 双指针, 先固定一个
        for (int i = 0; i < nums.size(); i++)
        {
            for (int j = i + 1; j < nums.size(); j++)
            {
                if (nums[i] + nums[j] == target)
                {
                    res[0] = i;
                    res[1] = j;
                    return res;
                }
            }
        }
        return res;
    }
};

方法3 AC代码:

​

class Solution {
    public:
        vector<int> twoSum(vector<int> &nums, int target)
        {
            unordered_map<int, int> dict;
            vector<int> result;
            for(int i = 0; i < nums.size(); i++) {
                dict[nums[i]] = i; // 顺序的map映射: value->index 
            }
            for(int i = 0; i < nums.size(); i++)
            {
                int query = target - nums[i];
                if(dict.find(query) != dict.end() && dict[query] > i)  // dict[query] > i是为了防止重复计算 
                {
                    result.push_back(i);
                    result.push_back(dict[query]);
                    break;
                }
            }
            return result;
        }
};

方法3的另一种写法:

class Solution {
public:
    vector<int> twoSum(vector<int> &nums, int target)
    {
        unordered_map<int, int> dict;
        vector<int> res(2,-1), emptyVect;
        for(int i=0;i<nums.size();i++)
        {
            int query=target-nums[i];
            if(dict.find(query)==dict.end()) dict[nums[i]]=i;     // 逆序的map映射: value->index
            else {
                res[1]=i;
                res[0]=dict[query];
                return res;
            }
        }
        return emptyVect;
    }
};

​

方法4 AC代码:

  • 定义一个struct, 存储 index 和 value

  • 使用两个指针, l 和 r, l++, r--

left自增, right 自减

注意: 如果要在一个struct上调用STL中的sort方法,需要先为其定义好 compare 函数。 ​

具体代码如下:

typedef struct node{
    int index;
    int value;
    node(){};
    node(int i, int v) : index(i), value(v){}
} Node;

bool compare(const Node& a, const Node& b){
    return a.value < b.value;
}

class Solution {
public:
    vector<int> twoSum(vector<int> &nums, int target) {

        int len = nums.size();
        assert(len >= 2);         

        vector<int> ret(2, 0);  // 初始化:ret包含2个值为0的元素

        vector<Node> nums2(len);
        for(int i = 0; i < len; i++){
            nums2[i] = Node(i+1, nums[i]);
        }

        sort(nums2.begin(), nums2.end(), compare);  // 在定义的struct上调用快排,T(n)=O(n*log(n))

        int l = 0;
        int r = len - 1;
        while(l < r){
            int sum = nums2[l].value + nums2[r].value;
            if(sum == target){
                ret[0] = min(nums2[l].index, nums2[r].index)-1;     // 注意,这里需要减去1
                ret[1] = max(nums2[l].index, nums2[r].index)-1;
                break;
            } else if(sum < target){
                l++;
            } else {
                r--;
            }
        }       
        return ret;  // 用两个指针来扫
    }
};
1. 两数之和