Lccup 力扣杯春季编程大赛 1、采购方案

题目描述

        小力将 N 个零件的报价存于数组 nums。小力预算为 target,假定小力仅购买两个零件,要求购买零件的花费不超过预算,请问他有多少种采购方案。

        注意:答案需要以 1e9 + 7 (1000000007) 为底取模,如:计算初始结果为:1000000008,请返回 1

示例 1:

输入:nums = [2,5,3,5], target = 6

输出:1

解释:预算内仅能购买 nums[0] 与 nums[2]。

示例 2:

输入:nums = [2,2,1,9], target = 10

输出:4

解释:符合预算的采购方案如下:
nums[0] + nums[1] = 4
nums[0] + nums[2] = 3
nums[1] +nums[2] = 3
nums[2] + nums[3] = 10

提示:

  • 2 <= nums.length <= 10^5
  • 1 <= nums[i], target <= 10^5

思路

        排序,然后遍历每个报价,累加每个报价和后面的报价可能组合,然后取模

        如何计算每个报价和后面的报价可能组合?用二分查找找到第一个比 taget - 当前报价 大的报价下标位置,两个下标的位置相减就是可能组合个数

class Solution {
public:
    int purchasePlans(vector<int>& nums, int target) {
        sort(nums.begin(),nums.end());
        int last=0,res=0,temp=0,n=nums.size();
        for(int i=0;i<n;++i){
            last=target-nums[i];
            //二分查找找到下标,从当前下标的后一个开始找,为什么事last+1呢,是因为lower_bound事查找第一个大于等于的,
            //所以要加一,不然找到等于的,而等于的刚好有多个,那不就漏算,可以改用upper_bound,查找第一个大于的
            temp=lower_bound(nums.begin()+i+1,nums.end(),last+1)-(nums.begin()+i+1);
            res=(res+temp)%int(1e9+7);
        }
        return res;     
    }
};

        可以改用upper_bound,查找第一个大于的也是通过的

temp=upper_bound(nums.begin()+i+1,nums.end(),last)-(nums.begin()+i+1);

别人的做法

        类似于双指针,找第一个比 taget - 当前报价 大的,看了好几个都是这么做的

class Solution {
public:
    int purchasePlans(vector<int>& nums, int target) {
        sort(nums.begin(), nums.end());
        int j = (int)nums.size() - 1;
        long long sum = 0;
        for (int i = 0; i < nums.size(); ++i) {
            while (j > i && nums[i] + nums[j] > target) {
                --j;
            }
            if (j > i)
                sum += j - i;
        }
        return sum % 1000000007;
    }
};
posted on 2021-06-06 18:32  雾恋过往  阅读(64)  评论(0编辑  收藏  举报

Live2D