[E双指针] lcLCP28. 采购方案(双指针+二分)

1. 题目来源

链接:LCP 28. 采购方案

2. 题目解析

简单问题,签到题。

排序后双指针很明显,不用多说。

二分的话比较恶心,首先,二分区间需要明确,是 [ i + 1 , n − 1 ] [i+1,n-1] [i+1,n1] 这个区间,不能自己买自己。要满足 a + b ≤ t a r g e t a+b\le target a+btarget,对于每一个 a a a,找到最大的一个 b b b 即可,在区间 [ i + 1 , n − 1 ] [i+1,n-1] [i+1,n1] 中寻找,找到最大的且满足 a + b ≤ t a r g e t a+b\le target a+btarget但是要注意一点, b b b 可能就没有合法的存在,仍会停在 i + 1 i+1 i+1 这个位置,也会产生一种方案。所以,需要在最后累加方案的时候判断一下,当前位置的 b b b,是否是合法的,即判断 a + b ≤ t a r g e t a+b\le target a+btarget 是否成立。


  • 时间复杂度 O ( n l o g n ) O(nlogn) O(nlogn)
  • 空间复杂度 O ( 1 ) O(1) O(1)

代码:

二分:

class Solution {
public:
    int purchasePlans(vector<int>& nums, int target) {
        const int MOD = 1e9 + 7;
        sort(nums.begin(), nums.end());
        long long res = 0;
        for (int i = 0; i < nums.size(); i ++ ) {
            int l = i + 1, r = nums.size() - 1;
            while (l < r) {
                int mid = l + r + 1 >> 1;
                if (nums[i] + nums[mid] > target) r = mid - 1;
                else l = mid;
            }
            if (nums[r] + nums[i] <= target) res += (r - i);
        }

        return res % MOD;
    }
};

双指针:

对于左指针 i i i 向右移动变大的过程中,右指针 j j j 不会再向右移动,只会向左移动。故满足双指针的性质。相当于一个窗口,慢慢变小,变小。

class Solution {
public:
    int purchasePlans(vector<int>& nums, int target) {
        const int MOD = 1e9 + 7;
        sort(nums.begin(), nums.end());
        long long res = 0;
        for (int i = 0, j = nums.size() - 1; i < nums.size(); i ++ ) {
            while (j > i && nums[i] + nums[j] > target) j -- ;
            if (j > i) res += j - i;
        }

        return res % MOD;
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Ypuyu

如果帮助到你,可以请作者喝水~

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

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

打赏作者

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

抵扣说明:

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

余额充值