[lintcode] 56.两数之和

描述

给一个整数数组,找到两个数使得他们的和等于一个给定的数 target

你需要实现的函数twoSum需要返回这两个数的下标, 并且第一个下标小于第二个下标。注意这里下标的范围是 0 到 n-1

 

样例

给出 numbers = [2, 7, 11, 15], target = 9, 返回 [0, 1].

挑战

Either of the following solutions are acceptable:

  • O(n) Space, O(nlogn) Time
  • O(n) Space, O(n) Time

解题思路

我一看这个O(nlogn) Time就开心了,一看就是二分查找嘛,结果给自己弄坑里去了:)

因为二分查找需要排序,排序会改变原始坐标,所以需要copy一个原始函数,判断copy函数的时候还要注意不能搞成相同的位置,踩完坑了之后终于过了。。后来随手一搜发现大家都hashMap O(n)搞定。我哈希函数学太差,只是感觉这个不是O(n)空间能搞定的,等我搞清楚hashMap咋回事再回来改。

代码

class Solution {
public:
    /**
     * @param numbers: An array of Integer
     * @param target: target = numbers[index1] + numbers[index2]
     * @return: [index1, index2] (index1 < index2)
     */
    int binary_search(vector<int> &numbers, int target, int low){
        int high = numbers.size()-1;
        int res = -1;
        while(low <= high){
            int mid = (low + high)/2;
            //cout << mid << endl;
            if(target == numbers[mid]){
                return mid;
            }
            else if(target < numbers[mid]){
                high = mid -1;
            }
            else{
                low = mid + 1;
            }
        }
        return res;
    }
    void copy(vector<int> &numbers, vector<int> &copy_num){
        for(int i=0; i<numbers.size(); i++){
            copy_num.emplace_back(numbers[i]);
        }
    }
    int get_prev_pos(vector<int> &numbers, vector<int> &copy_num, int pos, int start){
        int num = numbers[pos];
        cout << num << endl;
        for(int i=0; i<copy_num.size(); i++){
            if(i == start) continue;
            if(copy_num[i] == num) return i;
        }
        return -1;
    }
    
    vector<int> twoSum(vector<int> &numbers, int target) {
        // write your code here
        vector<int> copy_num;
        copy(numbers, copy_num);
        sort(numbers.begin(), numbers.end());
        int size = numbers.size();
        vector<int> res;
        for(int i=0; i<size; i++){
            int target_num = target - numbers[i];
            int pos = binary_search(numbers, target_num, i+1);
            if(pos != -1){
                int first = get_prev_pos(numbers, copy_num, i, -1);
                int second = get_prev_pos(numbers, copy_num, pos, first);
                if(first < second){
                    res.emplace_back(first);
                    res.emplace_back(second);
                }
                else{
                    res.emplace_back(second);
                    res.emplace_back(first);
                }
                return res;
            }
        }
        return res;
    }
};

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值