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.
Move from brute-force thinking to an efficient approach using array strategy.
Given an integer array nums and two integers left and right, return the number of contiguous non-empty subarrays such that the value of the maximum array element in that subarray is in the range [left, right].
The test cases are generated so that the answer will fit in a 32-bit integer.
Example 1:
Input: nums = [2,1,4,3], left = 2, right = 3 Output: 3 Explanation: There are three subarrays that meet the requirements: [2], [2, 1], [3].
Example 2:
Input: nums = [2,9,2,5,6], left = 2, right = 8 Output: 7
Constraints:
1 <= nums.length <= 1050 <= nums[i] <= 1090 <= left <= right <= 109Problem summary: Given an integer array nums and two integers left and right, return the number of contiguous non-empty subarrays such that the value of the maximum array element in that subarray is in the range [left, right]. The test cases are generated so that the answer will fit in a 32-bit integer.
Start with the most direct exhaustive search. That gives a correctness anchor before optimizing.
Pattern signal: Array · Two Pointers
[2,1,4,3] 2 3
[2,9,2,5,6] 2 8
count-subarrays-with-median-k)find-the-number-of-subarrays-where-boundary-elements-are-maximum)Source-backed implementations are provided below for direct study and interview prep.
// Accepted solution for LeetCode #795: Number of Subarrays with Bounded Maximum
class Solution {
public int numSubarrayBoundedMax(int[] nums, int left, int right) {
return f(nums, right) - f(nums, left - 1);
}
private int f(int[] nums, int x) {
int cnt = 0, t = 0;
for (int v : nums) {
t = v > x ? 0 : t + 1;
cnt += t;
}
return cnt;
}
}
// Accepted solution for LeetCode #795: Number of Subarrays with Bounded Maximum
func numSubarrayBoundedMax(nums []int, left int, right int) int {
f := func(x int) (cnt int) {
t := 0
for _, v := range nums {
t++
if v > x {
t = 0
}
cnt += t
}
return
}
return f(right) - f(left-1)
}
# Accepted solution for LeetCode #795: Number of Subarrays with Bounded Maximum
class Solution:
def numSubarrayBoundedMax(self, nums: List[int], left: int, right: int) -> int:
def f(x):
cnt = t = 0
for v in nums:
t = 0 if v > x else t + 1
cnt += t
return cnt
return f(right) - f(left - 1)
// Accepted solution for LeetCode #795: Number of Subarrays with Bounded Maximum
struct Solution;
impl Solution {
fn num_subarray_bounded_max(a: Vec<i32>, l: i32, r: i32) -> i32 {
let n = a.len();
let mut start = 0;
let mut end = 0;
let mut res = 0;
for i in 0..n {
if a[i] > r {
start = i + 1;
}
if a[i] >= l {
end = i + 1;
}
if start < end {
res += end - start;
}
}
res as i32
}
}
#[test]
fn test() {
let a = vec![2, 1, 4, 3];
let l = 2;
let r = 3;
let res = 3;
assert_eq!(Solution::num_subarray_bounded_max(a, l, r), res);
}
// Accepted solution for LeetCode #795: Number of Subarrays with Bounded Maximum
// Auto-generated TypeScript example from java.
function exampleSolution(): void {
}
// Reference (java):
// // Accepted solution for LeetCode #795: Number of Subarrays with Bounded Maximum
// class Solution {
// public int numSubarrayBoundedMax(int[] nums, int left, int right) {
// return f(nums, right) - f(nums, left - 1);
// }
//
// private int f(int[] nums, int x) {
// int cnt = 0, t = 0;
// for (int v : nums) {
// t = v > x ? 0 : t + 1;
// cnt += t;
// }
// return cnt;
// }
// }
Use this to step through a reusable interview workflow for this problem.
Two nested loops check every pair of elements. The outer loop picks one element, the inner loop scans the rest. For n elements that is n × (n−1)/2 comparisons = O(n²). No extra memory — just two loop variables.
Each pointer traverses the array at most once. With two pointers moving inward (or both moving right), the total number of steps is bounded by n. Each comparison is O(1), giving O(n) overall. No auxiliary data structures are needed — just two index variables.
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: Advancing both pointers shrinks the search space too aggressively and skips candidates.
Usually fails on: A valid pair can be skipped when only one side should move.
Fix: Move exactly one pointer per decision branch based on invariant.