2、两数之和II-输入有序数组

题目描述

给定一个已经按照升序排列的有序数组,找到两个数使得他们相加之和等于目标数。
函数应该返回这两个下标值index1和index2,其中index1必须小于index2。
说明:

  • 返回的下标值(index1和index2)不是从零开始的。
  • 你可以假设每个输入只对应唯一的答案,而且你不可以重复的使用相同的元素。

示例:

  • 输入:numbers = [2, 7, 11, 15], target = 9
  • 输出:[1, 2]
  • 解析:2与7之和等于目标数9。因此index1 = 1,index2 = 2。

解法:

  • 由于题目给出的数组是有序的了,所以可以使用二分法进行查找
  • 注意:题目要求返回的下标不是从0开始的,那么就是从1开始的了。
class Solution:
    # 变量后面的是类型的定义如:List[int],int等,返回值类型rtype:List[int]
    def twoSum(self, numbers: List[int], target: int) -> List[int]:
        # 数组有序之后可以使用二分法查找
        size = len(numbers)
        for i in range(size-1):
            # 初始化左指针和右指针 题目要求不能返回下标为0的,也就是第一个
            left = i+1 
            right = size - 1
            while left <= right:
                mid = (left+right)//2
                if numbers[i] + numbers[mid] < target:
                    left = mid + 1
                elif numbers[i] + numbers[mid] > target:
                    right = mid-1
                else:
                	# 返回的值从非0开始:
                    return [i+1,mid+1]
  • 官方给出的C++解法:
  • 使用双指针
class Solution {
public:
    vector<int> twoSum(vector<int>& numbers, int target) {
        int low=0,high = numbers.size() - 1;
        //如果刚开始两数之和就等于目标值就返回,否则双指针从两头向中间靠拢
        while (low < high){
        // 这里不需要考虑numbers[low] + numbers[high]溢出,因为即使两个元素之和溢出了,因为只存在唯一解,所以一定会先访问到答案。
            int sum = numbers[low] + numbers[high];
            if (sum == target)
                return {low + 1, high + 1};
            else if (sum < target)
                ++low;
            else
                --high;
        }
        // 找不到就返回-1,一定要返回一个东西,因为函数是non-void的
        return {-1,-1};
    };
};

算法分析:

我们可以使用 两数之和 的解法在 O(n^2)时间 O(1) 空间暴力解决,也可以用哈希表在 O(n)O(n) 时间和 O(n)O(n) 空间内解决。然而,这两种方法都没有用到输入数组已经排序的性质,我们可以做得更好。

我们使用两个指针,初始分别位于第一个元素和最后一个元素位置,比较这两个元素之和与目标值的大小。如果和等于目标值,我们发现了这个唯一解。如果比目标值小,我们将较小元素指针增加一。如果比目标值大,我们将较大指针减小一。移动指针后重复上述比较知道找到答案。

假设 [… , a, b, c, … , d, e, f, …][…,a,b,c,…,d,e,f,…] 是已经升序排列的输入数组,并且元素 b, eb,e 是唯一解。因为我们从左到右移动较小指针,从右到左移动较大指针,总有某个时刻存在一个指针移动到 bb 或 ee 的位置。不妨假设小指针县移动到了元素 bb ,这是两个元素的和一定比目标值大,根据我们的算法,我们会向左移动较大指针直至获得结果。

复杂度分析:

  • 时间复杂度:O(n)。每个元素最多被访问一次,共有n个元素。
  • 空间复杂度:O(1)。只是用了两个指针。

来源链接:https://leetcode-cn.com/problems/two-sum/solution/liang-shu-zhi-he-ii-shu-ru-you-xu-shu-zu-by-leetco/

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值