Offer 驾到,掘友接招!我正在参与2022春招打卡活动,点击查看活动详情。
每日刷题第72天 2021.03.30
LCP 28. 采购方案
- leetcode原题链接:leetcode-cn.com/problems/4x…
- 难度:简单
- 方法:双指针、二分
题目描述
- 小力将 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
解题思路
- 根据题意:需要任意选择两个零件,不能超过预算
target - 预处理:排序,将数组按非递减的顺序排列。
- 双指针:维护右端点,对于每一个右端点都可以往后找到匹配的数
- 举例:
nums = [1,2,2,9] - 对于第一个右端点
1,其可以匹配1,2、1,2、1,9 - 对于第二个右端点
2可以匹配2,2、2,9; - 对于第三个右端点
2可以匹配2,9 - 对于第四个右端点
9,其是最后一个,没有可以与之匹配的零件
- 举例:
- 根据上述的分析可得:
- 对于右端点
1而言,如果1 + 9 <= target,那么比数组中9所在的下标小的元素,和右端点1的加和,也一定<= target - 对于其他的右端点同理
- 因此:对于右端点
1符合的有1,2、1,2、1,9;对于右端点2符合的有2,2
- 对于右端点
AC代码
var purchasePlans = function(nums, target) {
nums.sort((a, b) => a - b);
let pre = 0,len = nums.length,last = len - 1;
let sum = 0;
while(pre < last) {
if(target >= nums[pre] + nums[last]){
// 找到界限
sum += last - pre;
pre++;
}else {
// 没有找到界限
last--;
}
}
return sum % 1000000007;
};
总结
- 双指针的做法比较精妙,重在思维上的理解