小力将 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
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/4xy4Wx
我的思路: 先剪枝,剪掉>=target的数据,然后再用最小的数与其他数相加,再用次小的数与比它大的数相加。(显然很复杂,不可取,去看大佬的思路,如下)
class Solution {
public:
int purchasePlans(vector<int>& nums, int target) {
//先剪枝,剪掉>=target的数据,然后再用最小的数与其他数相加,再用次小的数与比它大的数相加。
sort(nums,nums+nums.length,greater<int>());
}
};
大佬思路:
如果当前左右之和大于了目标值,说明偏大了,就把右指针往左移动
否则的话,说明找到了合适的,需要把两者中间的元素个数都累加起来,然后再向右移动左指针
class Solution {
public int purchasePlans(int[] nums, int target) {
int mood=1000000007;
int ans=0;
//从小到大排序
Arrays.sort(nums);
//定义两个指针,怎么定义?
int left=0;
int right=nums.length-1;
//之后再循环?改变指针的位置?NO,要加上判断条件
while(left<right){//如果left=right,有left与right同时指向的元素会相加,如果相加<target,那么ans会多加1
if(nums[left]+nums[right]>target){
right--;
}else{
ans+=right-left;
left++;
}
ans%=mood;
}
return ans%mood;
}
};