Count Subarrays Where Max Element Appears at Least K Times

medium array sliding window two pointers

Problem

Given an integer array nums and a positive integer k, return the number of contiguous subarrays in which the maximum element of the whole array appears at least k times within that subarray.

Inputnums = [1,3,2,3,3], k = 2
Output6
The array max is 3. The subarrays containing 3 at least twice are [1,3,2,3], [1,3,2,3,3], [3,2,3], [3,2,3,3], [2,3,3] and [3,3].

def countSubarrays(nums, k):
    mx = max(nums)                 # global maximum value
    res = 0
    left = 0
    cnt = 0                        # max-occurrences in window
    for right in range(len(nums)):
        if nums[right] == mx:
            cnt += 1
        while cnt >= k:            # shrink while window has k maxes
            if nums[left] == mx:
                cnt -= 1
            left += 1
        res += left                # left valid starts for this right
    return res
function countSubarrays(nums, k) {
  const mx = Math.max(...nums);      // global maximum value
  let res = 0, left = 0, cnt = 0;    // cnt = maxes in window
  for (let right = 0; right < nums.length; right++) {
    if (nums[right] === mx) cnt++;
    while (cnt >= k) {               // shrink while window has k maxes
      if (nums[left] === mx) cnt--;
      left++;
    }
    res += left;                     // left valid starts for this right
  }
  return res;
}
long countSubarrays(int[] nums, int k) {
    int mx = Integer.MIN_VALUE;
    for (int v : nums) mx = Math.max(mx, v);   // global max
    long res = 0;
    int left = 0, cnt = 0;                      // cnt = maxes in window
    for (int right = 0; right < nums.length; right++) {
        if (nums[right] == mx) cnt++;
        while (cnt >= k) {                      // shrink window
            if (nums[left] == mx) cnt--;
            left++;
        }
        res += left;                            // valid starts for right
    }
    return res;
}
long long countSubarrays(vector<int>& nums, int k) {
    int mx = *max_element(nums.begin(), nums.end()); // global max
    long long res = 0;
    int left = 0, cnt = 0;                           // cnt = maxes in window
    for (int right = 0; right < (int)nums.size(); right++) {
        if (nums[right] == mx) cnt++;
        while (cnt >= k) {                           // shrink window
            if (nums[left] == mx) cnt--;
            left++;
        }
        res += left;                                 // valid starts for right
    }
    return res;
}
Time: O(n) Space: O(1)