提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
LCCUP ‘21 力扣杯 春季编程大赛 - 个人赛第一题,提交了好几次都是超时,后面看了一下,还是基本功底不扎实。
采购方案
小力将 N 个零件的报价存于数组 nums。小力预算为 target,假定小力仅购买两个零件,要求购买零件的花费不超过预算,请问他有多少种采购方案。
注意:答案需要以 1e9 + 7 (1000000007) 为底取模,如:计算初始结果为:1000000008,请返回 1
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/contest/season/2021-spring/problems/4xy4Wx/
解题思路
最直接的想法就是暴力法循环遍历,不出所料,直接超时。
其实可以先对输入进行从小到大的排序,用两个指针 left 和 right 分别指向头和尾。因为是已经排好了序,所以当 left 和 right 指向的值之和小于或等于 target 时,在 left 和 right 之间的值必定也满足要求,就不需要再遍历中间这一部分值了;当 left 和 right 指向的值之和大于 target 时,在 left 和 right 之间可能还有值满足要求,所以需要将 right 左移继续遍历。因此写得代码如下:
class Solution {
public:
int purchasePlans(vector<int>& nums, int target) {
int ans = 0;
sort(nums.begin(), nums.end());
int left = 0, right = nums.size() - 1;
while(left < right){
if(nums[left] + nums[right] <= target){
ans += right - left;
left++;
}
else{
right--;
}
}
return ans % 1000000007;
}
};
然而,提交之后。。。。。。
爆炸了,有木有。。。。。。后来才发现每次计算的 right - left 时,定义的 int 会超额。。。。。。😰
优化后的代码
class Solution {
public:
int purchasePlans(vector<int>& nums, int target) {
long ans = 0;
sort(nums.begin(), nums.end());
int left = 0, right = nums.size() - 1;
while(left < right){
if(nums[left] + nums[right] <= target){
ans += (right - left) % 1000000007;
left++;
}
else{
right--;
}
}
return ans % 1000000007;
}
};
总结
大佬们都是两三分钟搞定的,自己还是差得很远。