美文网首页Leetcode程序员
LeetCode [1. Two Sum] 难度[easy]

LeetCode [1. Two Sum] 难度[easy]

作者: 数据挖掘机长 | 来源:发表于2017-04-24 12:15 被阅读0次

    题目

    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].


    解题思路

    题目的意思很简单,给你一个数组 nums[] 和一个target值,然后在该数组里找出两个元素,使得他们加起来的和等于target值,最后返回他们的indices。

    1. 最粗糙的方法肯定就是暴力求解啦,不过时间复杂度为 O(n^2), 为下下策。
    2. 接着再想到一个方法,那就是第一步先对数组排序,时间复杂度为 O(nlog(n))。 然后第二步设两个索引 a = 0, b = n-1, 如果 nums[a] + nums[b] > target, 则 b--;如果 nums[a] + nums[b] < target, 则 a++;如果 nums[a] + nums[b] = target, 则返回 a, b 值。第二步的时间复杂度为 O(n), 所以该算法总的时间复杂度为 O(nlog(n)),该算法的代码我没有贴出来,因为很容易就能写出来。
    3. 第三个方法是看到讨论区有人给出自己的解法,我看到挺有意思的。他是利用了哈希表的方法。原理也很简单,首先建立一个哈希表,然后遍历一遍数组,每次遍历的时候,检查在哈希表里是否存在一个元素,使得它们两个相加等于 target 值,如果有则输出答案,如果没有则将该遍历到的元素插进哈希表中,并记录下它的 index 值。遍历的时间复杂度为 O(n), 每次遍历的时候在哈希表里检索的时间为 O(log(n)), 所以总的复杂度也为 O(nlog(n)),但是那个人说是 O(n), 他认为哈希表里检索是不需要时间的,但我认为 unordered_map 里面使用红黑树实现的,检索是有代价的,所以我觉得复杂度为 O(nlog(n))。实现代码如下:

    参考代码

    一、排序方法

    class Solution {
    public:
        vector<int> twoSum(vector<int>& nums, int target) {
            vector<int> ans;
            unordered_map<int, int> hash, temp;
            //map<int, int> hash;
            for(int i=0;i<nums.size() ;i++){
                if(hash.find(nums[i])==hash.end())
                    hash[nums[i]]=i;
                else
                    temp[nums[i]]=i;
            }
            
            sort(nums.begin() ,nums.end());
            int i=0, j=nums.size()-1;
            while(i<j){
                if(nums[i]+nums[j]==target){
                    if(nums[i]==nums[j]){
                        ans.push_back(hash[nums[i]]);
                        ans.push_back(temp[nums[i]]);
                    }
                    else{  
                        ans.push_back(hash[nums[i]]);
                        ans.push_back(hash[nums[j]]); 
                    }
                    break;
                }
                else if(nums[i]+nums[j]<target)
                    i++;
                else
                    j--;
            }
            return ans;
        }
    };
    

    二、哈希方法

    class Solution {
    public:
        vector<int> twoSum(vector<int>& nums, int target) {
            //Key is the number and value is its index in the vector.
            unordered_map<int, int> hash;
            vector<int> result;
            for (int i = 0; i < nums.size(); i++) {
                int numberToFind = target - nums[i];
    
                //if numberToFind is found in map, return them
                if (hash.find(numberToFind) != hash.end()) {
                    //+1 because indices are NOT zero based
                    result.push_back(hash[numberToFind] );
                    result.push_back(i );           
                    return result;
                }
    
                //number was not found. Put it in the map.
                hash[nums[i]] = i;
            }
            return result;
        }
    };
    

    反思与总结

    有人会认为这题那么简单,为什么还要记录下来。我认为这题虽简单,但对我还是有一定启发的。因为对 unordered_map, map 等这些数据结构,虽然我了解他们的原理和实现,但往往在实际中很少会想起使用他们,从而导致自己的算法臃肿低效,所以我们应该在实战中多多利用这些封装性强,效率高效并且使用简单的数据结构,往往他们会出奇效~

    相关文章

      网友评论

        本文标题:LeetCode [1. Two Sum] 难度[easy]

        本文链接:https://www.haomeiwen.com/subject/bktpzttx.html