剑指Offer57.和为s的两个数字

  • 题目:剑指Offer57.和为s的两个数字
    一个有序数组nums,返回任意一对和为target的数字;
    若存在多对,则取二者乘积最小的一组;

  • 思路:
    1.双指针:O(n),O(1)
    数组本身有序,这是可以使用双指针的原因;
    之所以两侧遇到的的第一对就是乘积最小的,等价于一根绳子折成的四边形中,正方形面积最大

vector<int> twoSum(vector<int>& nums, int target) {
    int n = nums.size();
    if (n < 2) return {};

    for (int i = 0, j = n - 1; i < j; ) {
        int sum = nums[i] + nums[j];
        
        if (sum > target) --j;
        else if (sum < target) ++i;
        else return {nums[i], nums[j]};
    }

    return {};
}

2.若果本题要求随便找到一对组合,是可以的;但要求乘积最小,因为这种方式是边遍历边存,因此只有遇到某对组合的右边那个数才能查到,若在这之前提前遇到了另一对数的右边那个数,返回的就不是预期的最两侧的那对数了;例如数组为1~20,target=21,则目标为[ 1,20 ],但在这之前提前遇到了[ 10,11 ]
哈希表:时间O(n):遍历一次,最坏情况下目标数在数组末尾,就需要把n-1个数都insert进哈希表,insert操作是O(1),空间O(n):最坏需要存n-1个数

class Solution {
public:
    vector<int> twoSum(vector<int>& nums, int target) {
        unordered_set<int> us;
        for (auto x : nums) {
            if (us.find(target - x) != us.end()) return {target - x, x};
            else us.insert(x);
        }

        return {};
    }
};
  • 总结:
    对于O(n ^ 2)的,通常可以使用哈希表或双指针(双指针需要有序)将其优化为O(n);
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值