Leetcode 2444 || Count Subarrays With Fixed Bounds

Leetcode 2444 || Count Subarrays With Fixed Bounds

Leetcode Daily Challenge, March 04, 2023

·

4 min read

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 or nums[i]>maxK , we can't take the value in our subarray. So we need to consider i+1 as the starting point of the next subarray and set max_index and min_index as -1 .

  • If nums[i]=minK, we will keep it as the last visited index of minK in nums

  • If nums[i]=maxK , we will keep it as the last visited index of maxK in nums

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 to count only when c>0. Because, if there is no value equal to maxK or minK in nums, or there is no maxK and minK in any subarray, min(max_index,min_index) will return -1 , and c 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!