LeetCode-167

本文介绍了一道经典算法题“两数之和II”的两种解决方案:二分查找法和双指针法。该题要求在有序数组中找出两个数,使它们的和等于给定的目标值。文章详细解释了每种方法的实现思路,并提供了相应的C++代码示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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

题目
给定一个已按照非递减顺序排列的整数数组 numbers ,从数组中找出两个数满足相加之和等于目标数 target 。
函数应该以长度为 2 的整数数组的形式返回这两个数的下标值。numbers 的下标从 1 开始计数 ,所以答案数组应当满足 1 <= answer[0] < answer[1] <= numbers.length 。
假设每个输入只对应唯一的答案 ,而且不可以重复使用相同的元素。

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

题解

方法 1 二分查找

在数组中找到两个数,使其之和等于目标值 target,可以先固定一个数 x ,再寻找另一个数 target-x 。利用数组的有序性质,可以通过二分法查找。为了避免重复查找,固定第一个数后,第二个数只在第一个数右侧范围内查找。

方法 2 双指针

使用双指针缩小查找范围,直至找到目标位置。
初始时两指针分别指向首尾元素位置,计算指针指向元素之和。若两数之和等于目标值,则找到唯一解;若两数之和大于目标值,则右指针向左移动;若两数之和小于目标值,则左指针向右移动。
由于左指针从指向第一个元素位置开始,所以只需一直向右移动,向右移动时两数之和变大;由于右指针从指向最后一个元素位置开始,所以只需一直向左移动,向左移动时两数之和变小。因此,按照上述移动策略,两指针移动不会忽略可能的解。

更多题解

代码

方法 1 二分查找

class Solution {
public:
    vector<int> twoSum(vector<int>& numbers, int target) {
    	//固定第一个数
        for (int i = 0; i < numbers.size(); ++i) {
        	//在第一个数右侧查找第二个数
            int low = i + 1, high = numbers.size() - 1;
            //二分法查找
            while (low <= high) {
                int mid = (high - low) / 2 + low;
                if (numbers[mid] == target - numbers[i]) {
                    return {i + 1, mid + 1};
                } else if (numbers[mid] > target - numbers[i]) {
                    high = mid - 1;
                } else {
                    low = mid + 1;
                }
            }
        }
        return {-1, -1};
    }
};

方法 2 双指针

class Solution {
public:
    vector<int> twoSum(vector<int>& numbers, int target) {
    	//定义双指针
        int low = 0, high = numbers.size() - 1;
        while (low < high) {
            int sum = numbers[low] + numbers[high];
            if (sum == target) {
                return {low + 1, high + 1};
            } else if (sum < target) {
                ++low;
            } else {
                --high;
            }
        }
        return {-1, -1};
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值