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

Posted Ypuyu

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[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;
    }
};

以上是关于[E双指针] lcLCP28. 采购方案(双指针+二分)的主要内容,如果未能解决你的问题,请参考以下文章

leetcode28.实现strStr()(暴力拆解,双指针,KMP算法)

ABC260 E - At Least One(双指针)

codeforces 880E. Maximum Subsequence(折半搜索+双指针)

使用双指针暴力解决力扣28题《实现 strStr()》

ABC260 E - At Least One(双指针)

ABC260 E - At Least One(双指针)