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

思路

第一种:暴力,双重循环,时间复杂度O(n^2)
第二种:排序后,左右两侧搜索,时间复杂度O(n*log(n))

实现一

太久不写c++,首先尝试第一种熟悉一下。

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

本以为会超时,但是没想到过了=_=
不过运行时间的排名实在难看,在后4.39%

实现二

class Solution {
public:
    vector<int> twoSum(vector<int>& nums, int target) {
        vector<pair<int,int>> tmp;
        for(int i=0; i<nums.size(); i++){
            tmp.push_back(make_pair(nums[i], i));
        }
        sort(tmp.begin(), tmp.end());
        int i=0;
        int j=tmp.size()-1;
        while(tmp[i].first + tmp[j].first != target){
            if(tmp[i].first + tmp[j].first > target)
                j--;
            else
                i++;
            if(i>=j){
                break;
            }
        }
        return vector<int> {tmp[i].second, tmp[j].second};
    }
};

第一个考虑的问题是如何保存排序后的索引值,去了解了map,但是其键值不能重复。现在想想好像可以用multimap,当时没想到,就用了vector<pair<int,int>>再加上sort()实现。
第二个问题出在左右搜索上,一开始想着要从中间target/2处开始搜索,所以想了半天如何将lower_bound()用到排序好的数据上来。为此花了很多时间,甚至还尝试了自己写个lower_bound函数,但是总是报超时,也不知道为什么。后来一想从中间开始向两边搜索还要考虑一些边界问题,为什么不能从两边往中间搜索呢。一试就成功了,这次击败了82.02%的选手。
代码比较简单,这里就不阐述具体思路了,主要是熟悉下STL的运用。

思考

看了别人的代码,发现还有一种思路就是使用unordered_map加快查询,使查询时间复杂度为O(log(n)),这样通过对每个值查找配对的值也可以达到总体O(nlog(n))的时间复杂度。但是不知道为什么他不会因为重复的元素而报错,难道是unordered_map支持吗,这个还有待考证。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容