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

题目

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 等这些数据结构,虽然我了解他们的原理和实现,但往往在实际中很少会想起使用他们,从而导致自己的算法臃肿低效,所以我们应该在实战中多多利用这些封装性强,效率高效并且使用简单的数据结构,往往他们会出奇效~

    原文作者:腾古
    原文地址: https://www.jianshu.com/p/6178fd3910d1
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞