LeetCode 167 Two Sum II - Input array is sorted

题目:

Given an array of integers that is already sorted in ascending order, 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 and you may not use the same element twice.

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

题目链接

题意:

给一个数组ascending的数组,找到两个数之和等于target的值,要求这两个数序号不相同。

第一遍读题,ascending直接百度了下,,,给我的结果是攀升的,增加的,,,结果被好好的误导了一波,准确的意思应该是“非减”的,也就是说数组中同一个数可能出现多次。

第一次写没注意ascending的理解,直接枚举每一个数看是否存在(target - numbers[i]),没有处理数组中的数可能会重复的bug,结果毫无悬念TLE了。

ac的思路是利用二分查找,对当前的值二分查找[i+1, numbers.size()-1] 范围内有没有(target - numbers[i]),有的话就返回答案,若没有则继续利用二分查找 [i+1, numbers.size()-1] 范围内第一个比 numbers[i] 大的数,更新 i。

之所以第二次更新下标也需要二分查找,是因为有一次卡在了一组 输入时 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,....................,target=5 的数据上,,,对这种情况进行优化。

代码如下:

class Solution {
public:     
    // 找到[i+1, numbers.size()-1]范围之内,target-numbers[i]的位置
    int binarySerach_1(vector<int>nums, int key, int l, int r) {
        int m;
        while (l < r) {
            m = (l + r - 1) >> 1;
            if (nums[m] < key) 
                l = m + 1;
            else 
                r = m;
        }
        if (nums[r] == key) 
            return r;
        return -1;
    }
    // 找到[i+1, numbers.size()-1]范围之内,第一个比numbers[i]大的数的位置
    int binarySearch_2(vector<int>nums, int key, int l, int r) {
        int m;
        while (l < r) {
            m = (l + r - 1) >> 1;
            if (nums[m] <= key) 
                l = m + 1;
            else 
                r = m;
        }
        if (nums[r] > key) 
            return r;
        return -1;
    }
    vector<int> twoSum(vector<int>& numbers, int target) {  
        for (int i = 0; i < numbers.size(); i ++) {
            int addr = binarySerach_1(numbers, target-numbers[i], i + 1, numbers.size()-1);
            if (addr != -1) {
                return {i+1, addr + 1};
            }
            i = binarySearch_2(numbers, numbers[i], i + 1, numbers.size()-1) - 1;
        }
    }
};
还有另一种思路,因为整个数组是非减的,可以利用两个指针从两头开始往中间扫,假如两者所指向的值大于target,r--,否则l++,直到两者的值等于target。
代码如下:
class Solution(object):
    def twoSum(self, numbers, target):
        l = 0
        r = len(numbers)-1
        while l < r:
            temp = numbers[l] + numbers[r]
            if temp < target:
                l += 1
            elif temp > target:
                r -= 1
            else:
                return [l + 1, r + 1]


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值