欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Two Sum - LeetCode题解

程序员文章站 2022-03-08 11:37:57
...

1.Two Sum

Given an array of integers, return indices of the two numbers such that they add up to a specific target.

You may assume that each input would have exactly one solution, and you may not use the same element twice.

Example:

Given nums = [2, 7, 11, 15], target = 9,
Because nums[0] + nums[1] = 2 + 7 = 9,
return [0, 1].

首先,第一种做法就是用暴力枚举,在C++下可以通过,O(1)时间复杂度,但是两层循环枚举给他带来O(N^2)的空间复杂度,代码如下:

class Solution {
public:
    vector<int> twoSum(vector<int>& nums, int target) {
        /*暴力枚举*/
        for(int i = 0; i < nums.size() - 1; i++){
            for(int j = i + 1; j < nums.size(); j++){
                if(nums[i] + nums[j] == target){
                    return {i, j};
                }
            }
        }
        
        return {-1, -1};
    }
};

第二种,采用hash映射,用空间换时间,降低空间复杂度。想到用数组下标映射(桶),将数组的下标为该vector元素的值,数组元素的值为该vector元素的下标,这样就可以通过数组随机访问的性质得到vector元素的值及其在vector当中下标的映射。这种做法很巧妙,在并查集中也有应用。但是其缺点是,由于数组下标与元素的值相等,元素要非负数,否则就无法和非负的数组下标一一对应;元素的范围就是下标的范围,所以一旦vector中最大元素达到1000000,就要4MB的空间,再多点甚至会产生溢出,所以在这里也不适合。

第三种,采用STL自带的hash map,建立一个关于vector元素的值和vector元素下标的映射,接着顺序遍历vector元素,判断vector中是否有目标映射,他的键加上该元素等于目标和,则取出该元素的下标和该键值对的值就是能满足该和的下标。PS.注意如果目标和是当前元素的两倍,那么在hashmap中也可以找到该元素代码如下:

class Solution {
public:
    vector<int> twoSum(vector<int>& nums, int target) {
        /*两遍hash*/
        map<int, int> rec;
        
        // Add hash relations  
        for(int i = 0; i < nums.size(); i++){
            rec[nums[i]] = i;
        }
        
        // Search for coordinate record
        for(int i = 0; i < nums.size(); i++){
            if(rec.count(target - nums[i])){
                int index = rec[target - nums[i]];
                
                if(index != i){ // When the target isn't two times of the element
                    return {i, index};
                }
            }
        }
        
        return {-1, -1};
    }
};

第四种,其实只需要一遍hash

class Solution {
public:
    vector<int> twoSum(vector<int>& nums, int target) {
        /*一遍哈希*/
        map<int, int> rec;
        int l, r;
        
        for(l = nums.size() - 1; l >= 0; l--){
            if(rec.count(target - nums[l])){
                r = rec[target - nums[l]];
                
                if(r != l){
                    break;
                }
            }
            
            rec[nums[l]] = l;
        }
        
        return {l, r};
    }
};
相关标签: 题解 LeetCode