# 資訊 :::info - Question: 2958. Length of Longest Subarray With at Most $k$ Frequency - From: Leetcode Daily Challenge 2024.03.28 - Difficulty: Medium ::: --- # 目錄 :::info [TOC] ::: --- # 題目 You are given an integer array `nums` and an integer `k`. The **frequency** of an element `x` is the number of times it occurs in an array. An array is called **good** if the frequency of each element in this array is less than or equal to `k`. Return the length of the longest good subarray of `nums`. A subarray is a contiguous non-empty sequence of elements within an array. > Example 1: :::success - Input: `nums = [1,2,3,1,2,3,1,2]`, `k = 2` - Output: 6 - Explanation: 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. ::: > Example 2: :::success - Input: `nums = [1,2,1,2,1,2,1,2]`, `k = 1` - Output: `2` - Explanation: 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. ::: > Example 3: :::success - Input: `nums = [5,5,5,5,5,5,5]`, `k = 4` - Output: 4 - Explanation: 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. ::: > Constraints: :::success - 1 <= `nums.length` <= $10^5$ - 1 <= `nums[i]` <= $10^9$ - 1 <= `k` <= `nums.length` ::: --- # 解法 ## 概念 還是 sliding window,不過比昨天簡單一點點 基本上就是在 window 裡面的數值 frequency 一定會小於等於 `k`,如果超過我的第 10 - 18 行就會跳出來,跳出 while 迴圈應該就是計算答案並進到下一輪,而下一輪就是 `l+1` 這樣而已 小細節嘛。。其實 sliding window 要注意範圍問題,或說甚麼時候停下來,像這邊第 8 行就是 `l<n`,因為 `l` 要走到 `n-1` 的位置,而不是看 `r`,這邊要注意一下! 然後我要寫到睡著了。。 ## 程式碼 ```python= class Solution: def maxSubarrayLength(self, nums: List[int], k: int) -> int: freq = { nums[0]: 1 } l = 0 r = 1 ans = 1 n = len( nums ) while l < n: # r Move to the right most while r < n: if nums[r] not in freq: freq[nums[r]] = 1 r += 1 elif nums[r] in freq and freq[nums[r]] < k: freq[nums[r]] += 1 r += 1 else: break # Modify ans if ( r - l ) > ans: ans = r - l # Shift l one unit freq[nums[l]] -= 1 l += 1 return ans ``` --- # 複雜度 ## 時間複雜度 因為使用了 sliding window,基本上 `l` 會一直往後跑,`r` 也是,而且跑過的不會再重複跑一次,因為我沒有 `l` 往下扣或 `r` 往下扣的機制,所以會是 $O(2n) = O(n)$ ![TimeComplexity20240328](https://hackmd.io/_uploads/r1Hpw2zJR.png =80%x) ## 空間複雜度 空間的話因為有一個字典,所以是 $O(n)$ ![SpaceComplexity20240328](https://hackmd.io/_uploads/Bk5CDhGk0.png =80%x)