二分打卡5 167. 两数之和 II - 输入有序数组 笨比二分+滑动窗口+哈希

这篇博客探讨了三种解决两数之和问题的方法:二分查找、双指针和哈希查表。二分查找在有序数组中寻找目标值的补充,时间复杂度为O(n*logn);双指针法从数组两端向中间移动,找到和为目标值的元素,时间复杂度为O(n);哈希查表虽然查找速度快,但空间复杂度为O(n)。每种方法都有其适用场景和效率权衡。

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

  1. 两数之和 II - 输入有序数组
    给你一个下标从 1 开始的整数数组 numbers ,该数组已按 非递减顺序排列 ,请你从数组中找出满足相加之和等于目标数 target 的两个数。如果设这两个数分别是 numbers[index1] 和 numbers[index2] ,则 1 <= index1 < index2 <= numbers.length 。
    以长度为 2 的整数数组 [index1, index2] 的形式返回这两个整数的下标 index1 和 index2。
    你可以假设每个输入 只对应唯一的答案 ,而且你 不可以 重复使用相同的元素。
    你所设计的解决方案必须只使用常量级的额外空间。
    示例 1:
    输入:numbers = [2,7,11,15], target = 9
    输出:[1,2]
    解释:2 与 7 之和等于目标数 9 。因此 index1 = 1, index2 = 2 。返回 [1, 2]

笨比二分
从左到右以此找,判断target-arr[i]是不是存在
时间复杂度O(n*logn) 空间复杂度O(1)

class Solution {
public:
    vector<int> twoSum(vector<int>& numbers, int target) {
        int n=numbers.size();
        for(int i=0;i<n-1;++i)
        {
            int left=i+1,right=n-1;
            while(left<=right)
            {
                int mid=left+(right-left)/2;
                if(numbers[mid]>target-numbers[i])
                {
                    right=mid-1;
                }else if(numbers[mid]<target-numbers[i])
                {
                    left=mid+1;
                }else
                {
                    return {i+1,mid+1};
                }
            }

        }
        return {0,1};
    }
};

双指针
指左右两端,大于就右指针左移,小于就左指针右移,一定有一个刚好等于target
时间复杂度O(n),空间复杂度O(1)

class Solution {
public:
    vector<int> twoSum(vector<int>& numbers, int target) {
        int left=0,right=numbers.size()-1;
        while(numbers[left]+numbers[right]!=target)
        {
            if(numbers[left]+numbers[right]>target)
            {
                right--;
            }else
            {
                left++;
            }
        }
        return {left+1,right+1};
    }
};

哈希查表
用unoedered_map将值和下标映射,因为unordered_map底层是用哈希表实现的,因此查找速度很快,是O(1)级,但是需要占用大量内存,空间为O(n)。

时间复杂度:O(n),空间复杂度:O(n)。

class Solution {
public:
    vector<int> twoSum(vector<int>& numbers, int target) {
        unordered_map<int,int> book;
        int n=numbers.size();
        for(int i=0;i<n;i++)
        {
            if(book.find(target-numbers[i])!=book.end())
            {
                return {book[target-numbers[i]],i+1};
            }
            book.insert({numbers[i],i+1});
        }
        return{0,1};
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

下坠丷

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值