Off-by-one on range boundaries
Wrong move: Loop endpoints miss first/last candidate.
Usually fails on: Fails on minimal arrays and exact-boundary answers.
Fix: Re-derive loops from inclusive/exclusive ranges before coding.
Break down a hard problem into reliable checkpoints, edge-case handling, and complexity trade-offs.
The score of an array is defined as the product of its sum and its length.
[1, 2, 3, 4, 5] is (1 + 2 + 3 + 4 + 5) * 5 = 75.Given a positive integer array nums and an integer k, return the number of non-empty subarrays of nums whose score is strictly less than k.
A subarray is a contiguous sequence of elements within an array.
Example 1:
Input: nums = [2,1,4,3,5], k = 10 Output: 6 Explanation: The 6 subarrays having scores less than 10 are: - [2] with score 2 * 1 = 2. - [1] with score 1 * 1 = 1. - [4] with score 4 * 1 = 4. - [3] with score 3 * 1 = 3. - [5] with score 5 * 1 = 5. - [2,1] with score (2 + 1) * 2 = 6. Note that subarrays such as [1,4] and [4,3,5] are not considered because their scores are 10 and 36 respectively, while we need scores strictly less than 10.
Example 2:
Input: nums = [1,1,1], k = 5 Output: 5 Explanation: Every subarray except [1,1,1] has a score less than 5. [1,1,1] has a score (1 + 1 + 1) * 3 = 9, which is greater than 5. Thus, there are 5 subarrays having scores less than 5.
Constraints:
1 <= nums.length <= 1051 <= nums[i] <= 1051 <= k <= 1015Problem summary: The score of an array is defined as the product of its sum and its length. For example, the score of [1, 2, 3, 4, 5] is (1 + 2 + 3 + 4 + 5) * 5 = 75. Given a positive integer array nums and an integer k, return the number of non-empty subarrays of nums whose score is strictly less than k. A subarray is a contiguous sequence of elements within an array.
Start with the most direct exhaustive search. That gives a correctness anchor before optimizing.
Pattern signal: Array · Binary Search · Sliding Window
[2,1,4,3,5] 10
[1,1,1] 5
maximum-subarray)subarray-product-less-than-k)binary-subarrays-with-sum)Source-backed implementations are provided below for direct study and interview prep.
// Accepted solution for LeetCode #2302: Count Subarrays With Score Less Than K
class Solution {
public long countSubarrays(int[] nums, long k) {
int n = nums.length;
long[] s = new long[n + 1];
for (int i = 0; i < n; ++i) {
s[i + 1] = s[i] + nums[i];
}
long ans = 0;
for (int i = 1; i <= n; ++i) {
int l = 0, r = i;
while (l < r) {
int mid = (l + r + 1) >> 1;
if ((s[i] - s[i - mid]) * mid < k) {
l = mid;
} else {
r = mid - 1;
}
}
ans += l;
}
return ans;
}
}
// Accepted solution for LeetCode #2302: Count Subarrays With Score Less Than K
func countSubarrays(nums []int, k int64) (ans int64) {
n := len(nums)
s := make([]int64, n+1)
for i, x := range nums {
s[i+1] = s[i] + int64(x)
}
for i := 1; i <= n; i++ {
l, r := 0, i
for l < r {
mid := (l + r + 1) >> 1
if (s[i]-s[i-mid])*int64(mid) < k {
l = mid
} else {
r = mid - 1
}
}
ans += int64(l)
}
return
}
# Accepted solution for LeetCode #2302: Count Subarrays With Score Less Than K
class Solution:
def countSubarrays(self, nums: List[int], k: int) -> int:
s = list(accumulate(nums, initial=0))
ans = 0
for i in range(1, len(s)):
l, r = 0, i
while l < r:
mid = (l + r + 1) >> 1
if (s[i] - s[i - mid]) * mid < k:
l = mid
else:
r = mid - 1
ans += l
return ans
// Accepted solution for LeetCode #2302: Count Subarrays With Score Less Than K
impl Solution {
pub fn count_subarrays(nums: Vec<i32>, k: i64) -> i64 {
let n = nums.len();
let mut s = vec![0i64; n + 1];
for i in 0..n {
s[i + 1] = s[i] + nums[i] as i64;
}
let mut ans = 0i64;
for i in 1..=n {
let mut l = 0;
let mut r = i;
while l < r {
let mid = (l + r + 1) / 2;
let sum = s[i] - s[i - mid];
if sum * (mid as i64) < k {
l = mid;
} else {
r = mid - 1;
}
}
ans += l as i64;
}
ans
}
}
// Accepted solution for LeetCode #2302: Count Subarrays With Score Less Than K
function countSubarrays(nums: number[], k: number): number {
const n = nums.length;
const s: number[] = Array(n + 1).fill(0);
for (let i = 0; i < n; ++i) {
s[i + 1] = s[i] + nums[i];
}
let ans = 0;
for (let i = 1; i <= n; ++i) {
let [l, r] = [0, i];
while (l < r) {
const mid = (l + r + 1) >> 1;
if ((s[i] - s[i - mid]) * mid < k) {
l = mid;
} else {
r = mid - 1;
}
}
ans += l;
}
return ans;
}
Use this to step through a reusable interview workflow for this problem.
Check every element from left to right until we find the target or exhaust the array. Each comparison is O(1), and we may visit all n elements, giving O(n). No extra space needed.
Each comparison eliminates half the remaining search space. After k comparisons, the space is n/2ᵏ. We stop when the space is 1, so k = log₂ n. No extra memory needed — just two pointers (lo, hi).
Review these before coding to avoid predictable interview regressions.
Wrong move: Loop endpoints miss first/last candidate.
Usually fails on: Fails on minimal arrays and exact-boundary answers.
Fix: Re-derive loops from inclusive/exclusive ranges before coding.
Wrong move: Setting `lo = mid` or `hi = mid` can stall and create an infinite loop.
Usually fails on: Two-element ranges never converge.
Fix: Use `lo = mid + 1` or `hi = mid - 1` where appropriate.
Wrong move: Using `if` instead of `while` leaves the window invalid for multiple iterations.
Usually fails on: Over-limit windows stay invalid and produce wrong lengths/counts.
Fix: Shrink in a `while` loop until the invariant is valid again.