<p>You are given an integer array <code>nums</code> and an integer <code>k</code>.</p>

<p>The <strong>frequency</strong> of an element <code>x</code> is the number of times it occurs in an array.</p>

<p>An array is called <strong>good</strong> if the frequency of each element in this array is <strong>less than or equal</strong> to <code>k</code>.</p>

<p>Return <em>the length of the <strong>longest</strong> <strong>good</strong> subarray of</em> <code>nums</code><em>.</em></p>

<p>A <strong>subarray</strong> is a contiguous non-empty sequence of elements within an array.</p>

<p>&nbsp;</p>
<p><strong class="example">Example 1:</strong></p>

<pre>
<strong>Input:</strong> nums = [1,2,3,1,2,3,1,2], k = 2
<strong>Output:</strong> 6
<strong>Explanation:</strong> The longest possible good subarray is [1,2,3,1,2,3] since the values 1, 2, and 3 occur at most twice in this subarray. Note that the subarrays [2,3,1,2,3,1] and [3,1,2,3,1,2] are also good.
It can be shown that there are no good subarrays with length more than 6.
</pre>

<p><strong class="example">Example 2:</strong></p>

<pre>
<strong>Input:</strong> nums = [1,2,1,2,1,2,1,2], k = 1
<strong>Output:</strong> 2
<strong>Explanation:</strong> The longest possible good subarray is [1,2] since the values 1 and 2 occur at most once in this subarray. Note that the subarray [2,1] is also good.
It can be shown that there are no good subarrays with length more than 2.
</pre>

<p><strong class="example">Example 3:</strong></p>

<pre>
<strong>Input:</strong> nums = [5,5,5,5,5,5,5], k = 4
<strong>Output:</strong> 4
<strong>Explanation:</strong> The longest possible good subarray is [5,5,5,5] since the value 5 occurs 4 times in this subarray.
It can be shown that there are no good subarrays with length more than 4.
</pre>

<p>&nbsp;</p>
<p><strong>Constraints:</strong></p>

<ul>
	<li><code>1 &lt;= nums.length &lt;= 10<sup>5</sup></code></li>
	<li><code>1 &lt;= nums[i] &lt;= 10<sup>9</sup></code></li>
	<li><code>1 &lt;= k &lt;= nums.length</code></li>
</ul>

class Solution:
    def maxSubarrayLength(self, nums: List[int], k: int) -> int:
        # Idea: We track the left and right side of our subarray; i=0 and j=1
        # We count the occurrences for each element in a hashmap
        # We track if between i and j is a good or bad subarray
        # Good: increase j, add occurrences to the hashmap; update status [Good|Bad]
        # Bad: increase i, remove occurrences from hashmap; update status [Good|Bad]
        # Update maxlength if status = GOOD

        #Example
        # nums = [1,2,3,1,2,3,1,2], k = 2
        # i = 0; j = 1; hashmap = {1:1, 2:1}; status: GOOD; maxlenght=2; currlength=2
        # i = 0; j = 2; hashmap = {1:1, 2:1, 3:1}; status: GOOD
        # ...
        # i = 0; j = 5; hashmap = {1:2, 2:2, 3:2}; status: GOOD; maxlength=6; currlength=6
        # i = 0; j = 6; hashmap = {1:3, 2:2, 3:2}; status: BAD; maxlength=6; currlength=5
        # i = 1; j = 6; hashmap = {1:2, 2:2, 3:2}; status: GOOD; maxlength=6; currlength=6
        # ...

        if k >= len(nums):
            return len(nums)
        if k == 0:
            return 0
        el_to_occurrence = {}
        i = 0
        j = 0
        curr_len = 0
        max_len = 0
        is_good = True
        bad_els = set()
        while j < len(nums):
            if is_good:
                el = nums[j]
                if el in el_to_occurrence:
                    el_to_occurrence[el] +=1
                else:
                    el_to_occurrence[el] = 1
                
                curr_occurrence = el_to_occurrence[el]
                curr_len += 1
                if curr_occurrence > k:
                    is_good = False
                    bad_els.add(el)
                else:
                    max_len = max(max_len, curr_len)
                    j+=1
            else:
                el = nums[i]
                if el in el_to_occurrence:
                    el_to_occurrence[el] -=1
                else:
                    raise Exception("We should never reach this")
                curr_occurrence = el_to_occurrence[el]
                curr_len -= 1
                i += 1
                if curr_occurrence <= k:
                    if el in bad_els:
                        bad_els.remove(el)
                    if(len(bad_els) == 0):
                        is_good = True
                        j += 1
                        max_len = max(max_len, curr_len)
        return max_len

1263