leetcode 1.Two Sum

准备互联网招聘的过程中leetcode和剑指offer是标配的,虽然自己目前为止已经刷了200题了,但是回头一看很多思路都忘了或者是再写代码的时候不能够一次free bug通过,因此从1开始慢慢总结的,如果有问题的话希望大家能够在评论下方交流,我很乐意能够跟大家交流,一起进步学习,拿下BAT ATM。也许有人会说现在的题解已经是够多了,但是呢这个博客是记录个人成长的一个部分的,同时也是希望能够用最简单的语言和分析能够帮助大家开始leetcode刷题之旅的。

在准备招聘的过程中一定是艰辛而孤独的,每天需要跑招聘会,还要学会整理和收集资料,就像徒步沙漠一样难熬和辛苦,虽然时常失望但仍旧怀抱期待,相信只要坚持下去你就能够做自己的神,最终有所收获的! 好了,就不接着灌鸡汤了,开启新的旅程吧!

 

链接:https://leetcode.com/problems/two-sum/description/ 

题意: 在给定的数组之中寻找一对值使得这两个数的和为target目标值的,最终答案是返回下标值。

考察要点:这个问题被分类到 “数组,哈希表” 问题的,其中哈希表是使用 键-值 映射对的,键可以是某种类型的也可以是多种类型的组合的,如在后面的题目中是可以看到如pair<int, string>的组合键的形式的。哈希表作为一种常用的数据结构,其优势在于能够提供常数O(1)时间复杂度的插入和删除操作的。因此当遇到暴力法超时的时候而同时又会有大量的中间重复结果被使用的时候就可以考虑哈希表了,如在后面的题目中会遇到的保持动态规划的中间值的时候就能够避免大量的运算量了。

因此最简单暴力的方法就是o(n^2)的两个for循环了,耗时是128ms的。

class Solution {
public:
    vector<int> twoSum(vector<int>& nums, int target) {
        vector<int> res;
        for(int i=0;i<nums.size();i++)
        {
            for(int j=i+1;j<nums.size();j++)
            {
                if(nums[i]+nums[j]==target)
                {
                    res.push_back(i);
                    res.push_back(j);
                    return res;
                }
            }
        }
    }
};

接下来来看使用哈希表的结果的,可以提前将数组中的值和下标组成键值对的,map.count函数是在哈希表中寻找被查找元素的个数的,如果有的话就返回1(不会真的返回元素的个数的),否则的话就返回0,因此返回值只能是1或者0。 还有另外一种方式来查找主键是否存在的,使用map.find函数返回被查找元素的位置的,没有的话就返回map.end()的,因为find函数返回的是迭代器的,所以需要提前构造迭代器的,如注释中的it。

因此在哈希表中寻找会不会出现的时候就可以利用两个条件了: map.count() ? 0 或者是 map.find() ? map.end()的 判断方法的。

这个方法是o(n)的,因为哈希表中的插入和搜索都是o(1)的,耗时是8ms。

class Solution {
public:
    vector<int> twoSum(vector<int>& nums, int target) {
        vector<int> res;
        map<int,int> mp;
     // map<int, int>::iterator it 构造迭代器
for(int i=0;i<nums.size();i++) mp[nums[i]]=i; for(int i=0;i<nums.size();i++) { int search=target-nums[i];
       // it=mp.find(search);
       // if(it!=mp.end() && i!=mp[search]) 利用find函数时,同时需要注意特殊情况一个数字使用了两次的如6=3+3
if(mp.count(search) && i!=mp[search]) { res.push_back(i); res.push_back(mp[search]); break; } } return res; } };

其实上述方式可以优化为只使用一次循环的,这样的话也不用单独判断特殊情况的,但如果下标需要按照[小,大]输出的话需要注意对应的顺序的。耗时是4ms。

class Solution {
public:
    vector<int> twoSum(vector<int>& nums, int target) {
        vector<int> res;
        map<int,int> mp;
        for(int i=0;i<nums.size();i++)
        {
            int search=target-nums[i];
            if(mp.count(search))
            {
                res.push_back(mp[search]);
                res.push_back(i);
                break;
            }
            mp[nums[i]]=i;
        }
        return res;
    }
};

 

posted on 2018-08-31 09:35  昔风不止,唯有努力生存  阅读(209)  评论(0编辑  收藏  举报

导航