Leetcode 2444 || Count Subarrays With Fixed Bounds
Leetcode Daily Challenge, March 04, 2023
Problem
https://leetcode.com/problems/count-subarrays-with-fixed-bounds/
In this problem, a list nums
along with maxK
and minK
values are given as input. We need to count the subarrays where the maximum value = maxK
and minimum value = minK .
Solution
Let's think of a brute-force approach first. Then an efficient solution. We will code this solution in python.
Brute Force
We can find all the possible subarrays and check the minimum and maximum values. We can keep the count if minimum and maximum values are the same as the given minK
and maxK
. Then return the count.
Let's look at this example :
Input: nums = [1,3,5,2,7,5], minK = 1, maxK = 5
Output: 2
All subarrays :
[1]
[1, 3]
[1, 3, 5]--------> count : 1
[1, 3, 5, 2]--------> count : 2
[1, 3, 5, 2, 7]
[1, 3, 5, 2, 7, 5]
[3]
[3, 5]
[3, 5, 2]
[3, 5, 2, 7]
[3, 5, 2, 7, 5]
[5]
[5, 2]
[5, 2, 7]
[5, 2, 7, 5]
[2]
[2, 7]
[2, 7, 5]
[7]
[7, 5]
[5]
Now you can see how we are solving this problem. Let's do it in code now.
So, how to find all the subarrays? Well, we can two nested loops to find all the subarrays. Look at the code below :
class Solution:
def countSubarrays(self, nums: List[int], minK: int, maxK: int) -> int:
count = 0
for i in range(len(nums)):
for j in range(i,len(nums)):
subarr = nums[i:j+1]
maxx = max(subarr)
minn = min(subarr)
if maxx==maxK and minn==minK:
count += 1
return count
The problem with this code is its time complexity. Time complexity is O(n). So in leetcode, if you submit this solution you will get Time Limit Exceeded error.
Let's think of an efficient solution now.
Efficient Solution : Time complexity O(n) , space complexity O(1)
We can use two pointers to solve this problem. These two pointers will point to the index of the given minK
and maxK
in nums
respectively.
Then we will iterate through nums
only once and keep counting our desired subarrays.
Look at the code first to understand better :
class Solution:
def countSubarrays(self, nums: List[int], minK: int, maxK: int) -> int:
max_index, min_index = -1,-1
count = 0
i,restart = 0,0
while i<len(nums):
if nums[i]<minK or nums[i]>maxK:
restart = i+1
max_index, min_index = -1,-1
if nums[i]==minK:
min_index = i
if nums[i]==maxK:
max_index = i
c = 1 + min(max_index,min_index) - restart
count += c if c>=0 else 0
i += 1
return count
If the
nums[i] < minK
ornums[i]>maxK
, we can't take the value in our subarray. So we need to consideri+1
as the starting point of the next subarray and setmax_index
andmin_index
as-1
.If
nums[i]=minK
, we will keep it as the last visited index ofminK
innums
If
nums[i]=maxK
, we will keep it as the last visited index ofmaxK
innums
The toughest part of this code to understand could be this line :
c = 1 + min(max_index,min_index) - restart
No worries, I will explain now what are we doing in this line.
Let me explain with the example below:
nums = [1,2,17,17,7,8,17,1,5,4,5,3,17], minK = 1, maxK = 17
when , min_index = 0 max_index = 2
Along with [1,2,17] we will look for any values that could create a valid subarray, here c = 0
............
when , min_index = 7 max_index = 6, min(max_index,max_index)=6
this 6 are : [8,17,1]
[7,8,17,1]
[17,7,8,17,1]
[17,17,7,8,17,1]
[2,17,17,7,8,17,1]
[1,2,17,17,7,8,17,1]
and that 1 subarray we are adding in c is [17,1]
Do you get it now? This is how we are iterating nums
only once and counting all the possible subarrays.
To make clear further confusion,
- We are adding
c
tocount
only whenc>0
. Because, if there is no value equal tomaxK
orminK
innums
, or there is nomaxK
andminK
in any subarray,min(max_index,min_index)
will return-1
, andc
will be a negative number, which means no valid subarray. That's why we are counting count when c>0
Thanks for reading this far. I really appreciate that you took the time to read this article. Let me know any confusion or questions in the comment. Don't forget to give thumbs up if you like this writing.
Thank You. Happy Coding!