采购方案
难度:
标签:
题目描述
English description is not available for the problem. Please switch to Chinese.
代码结果
运行时间: 136 ms, 内存: 26.7 MB
/*
* 思路:
* 1. 对数组进行排序。
* 2. 使用双指针方法,通过Stream API的简化处理。
* 3. 将双指针的逻辑封装在一个for循环中。
* 4. 若两数之和小于等于目标值,则将符合条件的配对计数加上,左指针右移。
* 5. 否则右指针左移。
* 6. 使用 1e9 + 7 对结果取模。
*/
import java.util.Arrays;
import java.util.stream.IntStream;
public class Solution {
public int purchasePlans(int[] nums, int target) {
Arrays.sort(nums);
final int MOD = 1000000007;
long count = IntStream.range(0, nums.length)
.mapToLong(left -> {
int right = nums.length - 1;
long localCount = 0;
while (left < right) {
if (nums[left] + nums[right] <= target) {
localCount += right - left;
localCount %= MOD;
left++;
} else {
right--;
}
}
return localCount;
})
.sum() % MOD;
return (int) count;
}
}
解释
方法:
此题解使用了双指针技巧。首先,将数组排序,然后使用两个指针,一个指向数组的开始(左指针),另一个指向数组的末尾(右指针)。左指针代表的是较小的数,右指针代表的是较大的数。不断检查两个指针所指的数之和是否小于等于目标值 target。如果是,则所有介于左指针和右指针之间的组合都满足条件(因为数组是排序的,所以右指针左边的任何一个数字加上左指针的数字都会小于等于target),于是将这些组合计入答案中。然后移动左指针向右寻找新的组合。如果两数之和大于 target,则移动右指针向左以减小数值之和。这个过程持续到左指针不再小于右指针。
时间复杂度:
O(n log n)
空间复杂度:
O(log n)
代码细节讲解
🦆
为什么在这个问题中选择对数组进行排序是一个必要的步骤?
▷🦆
在双指针策略中,当左指针和右指针指向的元素之和小于等于目标时,为什么可以直接添加 `r - l` 到答案中,这种计算方式的正确性是如何保证的?
▷🦆
如果在某些特殊情况下,所有的数组元素都非常接近 `target`,这种双指针方法的表现如何?会不会影响算法的效率?
▷