Count Subarrays Where Max Element Appears at Least K Times
MedPrompt
You are given an integer array nums and a positive integer k.
Return the number of subarrays where the maximum element of nums appears at least k times in that subarray.
A subarray is a contiguous sequence of elements within an array.
Example 1:
Input: nums = [1,3,2,3,3], k = 2
Output: 6
Explanation: The subarrays that contain the element 3 at least 2 times are: [1,3,2,3], [1,3,2,3,3], [3,2,3], [3,2,3,3], [2,3,3] and [3,3].Example 2:
Input: nums = [1,4,2,1], k = 3
Output: 0
Explanation: No subarray contains the element 4 at least 3 times.
Constraints:
1 <= nums.length <= 1051 <= nums[i] <= 1061 <= k <= 105
Approaches
2 approaches with complexity analysis and trade-offs.
This approach involves systematically checking every possible contiguous subarray within the nums array. We use two nested loops to define the start and end of each subarray. For each subarray, we count the occurrences of the global maximum element and check if the count meets the k threshold.
Algorithm
- First, find the maximum element
maxValin the entirenumsarray. - Initialize a result counter,
ans, to zero. - Use a nested loop to iterate through all possible subarrays. The outer loop with index
idefines the start of the subarray, and the inner loop with indexjdefines the end. - For each starting position
i, initialize a countercurrentMaxCountto 0. - As the inner loop for
jprogresses fromiton-1, check ifnums[j]is equal tomaxVal. If it is, incrementcurrentMaxCount. - If
currentMaxCountbecomes greater than or equal tok, it means the subarraynums[i...j]is valid. From this point on, for this fixedi, all subsequent subarraysnums[i...j+1],nums[i...j+2], etc., will also be valid. - Therefore, once
currentMaxCount >= k, we can add the remaining number of subarrays, which isn - j, to ouransand break the inner loop to move to the nexti. - After iterating through all possible starting points
i,answill hold the total count.
Walkthrough
The brute-force method is the most straightforward way to solve the problem.
- First, we iterate through the entire array to find its maximum element, let's call it
maxVal. - We then initialize a variable
ansto 0, which will store our final count of valid subarrays. - We use a pair of nested loops. The outer loop, with index
i, iterates from0ton-1and sets the starting point of our subarrays. - The inner loop, with index
j, iterates fromiton-1, setting the ending point. This(i, j)pair defines the subarraynums[i...j]. - For each subarray, we count the number of times
maxValappears. To optimize this slightly from a naive O(N^3) approach, we can maintain a running count ofmaxValwithin the inner loop. - When the count of
maxValinnums[i...j]reaches or exceedsk, we increment ourans. A further optimization is to notice that ifnums[i...j]is valid, so isnums[i...j+1],nums[i...j+2], etc. So, once a valid subarray is found, we can add all remaining extensions to the answer and break the inner loop.
class Solution { public long countSubarrays(int[] nums, int k) { int maxVal = 0; for (int num : nums) { maxVal = Math.max(maxVal, num); } long ans = 0; int n = nums.length; for (int i = 0; i < n; i++) { int currentMaxCount = 0; for (int j = i; j < n; j++) { if (nums[j] == maxVal) { currentMaxCount++; } if (currentMaxCount >= k) { // If nums[i..j] is valid, then nums[i..j+1], nums[i..j+2], ..., nums[i..n-1] are also valid. // There are (n-1) - j + 1 = n - j such subarrays. ans += (n - j); break; // Move to the next starting position i } } } return ans; }}Complexity
Time
O(N^2) in the worst case. Finding the maximum element takes O(N). The nested loops run in O(N^2) time, leading to a total complexity dominated by the loops.
Space
O(1), as we only use a few variables to store the maximum value, counters, and loop indices.
Trade-offs
Pros
The logic is simple and easy to understand.
It's a direct implementation of the problem statement.
Cons
The O(N^2) time complexity is too slow for the given constraints (N up to 10^5) and will result in a 'Time Limit Exceeded' error on most platforms.
Solutions
Solution
class Solution {public long countSubarrays(int[] nums, int k) { int mx = Arrays.stream(nums).max().getAsInt(); int n = nums.length; long ans = 0; int cnt = 0, j = 0; for (int x : nums) { while (j < n && cnt < k) { cnt += nums[j++] == mx ? 1 : 0; } if (cnt < k) { break; } ans += n - j + 1; cnt -= x == mx ? 1 : 0; } return ans; }}Video walkthrough
Newsletter
One sharp idea, every week
System design and interview prep — short enough to finish.
No spam. Unsubscribe anytime.
Practice
Same difficulty — related problems to reinforce the pattern.