LeetCode 1 - Two Sum

来源:互联网 发布:淘宝优惠券公众号排名 编辑:程序博客网 时间:2024/05/17 04:12

问题简述

  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.

Example:

Given nums = [2, 7, 11, 15], target = 9,

Because nums[0] + nums[1] = 2 + 7 = 9,
return [0, 1].

我的解答

这让我想起之前遇到过一道3-Sum Problem,即在数组中找3个数和为0(或其他值),只是这道题算是3-Sum的子问题。

最trivial的的解法应该是两层循环搜索,时间复杂度是O(n2),这在这道题也能过。

我想到的另外一种,就来自于3-Sum的解法:将数组排序,然后定义两个指针i、j分别指向排序后数组的第一个元素与最后一个元素。当arr[i]+arr[j]

#include <iostream>#include <vector>#include <algorithm>using namespace std;class Solution {public:    vector<int> twoSum(vector<int>& nums, int target)    {        vector<int>re;        vector<pair<int,int> > val_pos(nums.size());        for(int i=0;i<nums.size();i++)        {            val_pos[i]={nums[i],i};        }        sort(val_pos.begin(),val_pos.end(),[](const pair<int,int>& a, const pair<int,int>& b){return a.first<b.first;});//只根据pair的第一项排序        int i=0,j=nums.size()-1;        while(1)        {            if(val_pos[i].first+val_pos[j].first<target)                i++;            else if(val_pos[i].first+val_pos[j].first>target)                j--;            else            {                re.push_back(val_pos[i].second);                re.push_back(val_pos[j].second);                return re;            }        }        return re;    }};

Editorial的解法

我后来还看了一下Editorial中的解法,发现还可以用哈希表来加速查询。在这种方法下,我们可以只遍历一次数组就可以找到解。

我在这里直接生造了一个哈希表,Chaining的实现。不过C++ STL确有Hashmap的实现(我写完后才想起来)。

时间复杂度O(n),空间复杂度O(n)。这个方法确实比我之前的方法要快一点。

#include <iostream>#include <vector>#include <list>#include <algorithm>#include <cmath>using namespace std;class Solution {public:    int mod(int n,int m) //应对负数的取模操作    {        if(n>=0)            return n%m;        else        {            while(n<0)n+=m;            return n;        }    }    vector<int> twoSum(vector<int>& nums, int target)    {        int prime = 1;        vector<list<pair<int,int> > >hash(prime);        for(int i=0;i<nums.size();i++)        {            int tgt_addr=mod((target-nums[i]),prime);            if(hash[tgt_addr].empty())//Hash表对应位置是否为空?            {                hash[mod(nums[i],prime)].push_back({nums[i],i});            }            else            {                for(auto it=hash[tgt_addr].begin();it!=hash[tgt_addr].end();it++)//能不能找到该元素?                {                    if(it->first==target-nums[i])                    {                        return {it->second,i};                    }                }                hash[mod(nums[i],prime)].push_back({nums[i],i});//找不到,将当前元素放置到Hash表相应位置            }        }        return {};    }};
0 0