统计得分小于 K 的子数组数目
难度:
标签:
题目描述
代码结果
运行时间: 135 ms, 内存: 28.0 MB
/*
* 思路:
* 使用Java Stream API来计算满足条件的子数组数量。
* 这里使用滑动窗口的方法,遍历每一个子数组并计算分数。
*/
import java.util.stream.IntStream;
public class Solution {
public long numSubarrayScoreLessThanK(int[] nums, long k) {
int n = nums.length;
return IntStream.range(0, n)
.flatMap(start -> IntStream.range(start, n)
.map(end -> {
int sum = 0;
for (int i = start; i <= end; i++) {
sum += nums[i];
}
return (sum * (end - start + 1) < k) ? 1 : 0;
}))
.sum();
}
}
解释
方法:
这是一道使用双指针技术解决的问题。我们初始化两个指针left和right,分别代表子数组的左右边界。我们从左到右遍历数组,每次将right指向的元素加到当前的分数中,然后检查当前子数组的分数是否小于k。如果分数大于或等于k,我们就移动left指针,直到分数再次小于k。每次迭代中,以right为右端点的符合条件的子数组数量就是right - left + 1,我们将这个值累加到最终答案中。
时间复杂度:
O(n)
空间复杂度:
O(1)
代码细节讲解
🦆
题解中提到,当分数大于等于k时,left指针向右移动,这是否意味着只有当添加新元素导致总分数超过k时,我们才调整left指针?
▷🦆
在计算子数组的分数时,为何使用累加的方式更新score而不是每次都重新计算子数组的和?这种方法在什么情况下可能导致错误?
▷🦆
类Solution中的while循环条件是`score * lens >= k`,那么在score非常大或lens非常大的情况下,这种方法是否还是有效的?
▷🦆
题解中的算法是否考虑了所有子数组的边界条件,例如最小子数组和最大子数组?
▷