Two Sum

题目:

Given an array of integers, find two numbers such that they add up to a specific target number.

The function twoSum should return indices of the two numbers such that they add up to the target, where index1 must be less than index2. Please note that your returned answers (both index1 and index2) are not zero-based.

You may assume that each input would have exactly one solution.

Input: numbers={2, 7, 11, 15}, target=9
Output: index1=1, index2=2

对于这道题,有两种解答方法,一种是用排序和双指针,另一种是用hash表,下面具体来说。

快速排序+双指针解法:

先将numbers数组从小到大进行快速排序,然后一个index i 从numbers[0]开始,另一个index j 从numbers的结束开始,往中间靠拢。在这个靠拢过程中,如果numbers[i] + numbers[j] < target 说明加和的值还不够,需要继续增加,那只能增大i了(因为numbers从小到大排序),如果numbers[i] + numbers[j] > target 说明加和的值大了,需要减小点,那也只能减小j了,如果numbers[i] + numbers[j] == target , 那说明我们找到了答案。由于题目要求给出原来数组中的位置,并且第一个数位置为1(而不是0),因此我们需要一个额外的数组暂存原来的数组,然后找到在原始数组中的位置。
算法的时间复杂度是:快排O(nlogn) + 双指针O(n) + 找位置 O(n)  = O(nlogn) ,由于用到了一个额外数组,空间复杂度是O(n)。
AC的代码如下:

class Solution {
public:
    vector<int> twoSum(vector<int> &numbers, int target) {
        vector<int> result,tmp = numbers;
        int a = 0,b = 0;
        sort(tmp.begin(),tmp.end());
        int i = 0 ,j = tmp.size()-1;
        while(i<j){
            if(tmp[i]+tmp[j] == target) break;
            else if (tmp[i]+tmp[j] > target) --j;
            else ++i;
        }
        for(int w = 0 ; (!a||!b)&&w < numbers.size();++w){
            if((!a)&&numbers[w] == tmp[i]) a = w+1;
            else if(numbers[w] == tmp[j]) b = w+1;
        }
        result.push_back(a<b?a:b);
        result.push_back(a>b?a:b);
        return result;
    }
};


hash表解法:

这种解法很简单,就是建立 <numbers[i],i> 这一对索引,遍历一遍numbers, 然后用target-numbers[i] 去找hash 表 ,如果存在 ,取出i,搞定!

时间复杂度是O(n), 空间复杂度是hash表的大小。

AC代码如下:

vector<int> twoSum(vector<int> &numbers, int target){
    unordered_map<int, int> hash;
    vector<int> result;
    for (int i = 0; i < numbers.size(); i++{
        int numberToFind = target - numbers[i];
        if (hash.find(numberToFind) != hash.end()) {
            result.push_back(hash[numberToFind] + 1);
            result.push_back(i + 1);            
            return result;
        }
        hash[numbers[i]] = i;
    }
    return result;
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值