right−left+1 為目前窗口內元素 x 的數量。
兩者相減,即為窗口內非 x 元素的數量,也就是需要刪除的元素數量,若大於 k,則需要開始縮小窗口,最後更新答案即可。
複雜度分析
時間複雜度:O(n),其中 n 為陣列 nums 的長度,需要遍歷所有元素。
空間複雜度:O(n),需要 O(n) 的空間來存儲每個元素出現的位置。
1 2 3 4 5 6 7 8 9 10 11 12 13 14
classSolution: deflongestEqualSubarray(self, nums: List[int], k: int) -> int: n = len(nums) pos = defaultdict(list) # 紀錄每個元素出現的位置 for i, x inenumerate(nums): pos[x].append(i) ans = 0 for x, lst in pos.items(): left = 0# left, right 為窗口的左右邊界,是 pos[x] 中的下標 for right, idx inenumerate(lst): while (idx - lst[left] + 1) - (right - left + 1) > k: # 若不符合條件,則開始縮小窗口 left += 1 ans = max(ans, right - left + 1) # 更新答案 return ans
classSolution { public: intlongestEqualSubarray(vector<int>& nums, int k){ int n = nums.size(); vector<vector<int>> pos(n + 1); // 紀錄每個元素出現的位置,1 <= nums[i] <= nums.length for (int i = 0; i < n; i++) { pos[nums[i]].push_back(i); } int ans = 0; for (int x = 1; x <= n; x++){ if (pos[x].empty()) continue; // 若元素 x 不存在,則跳過 int left = 0; // left, right 為窗口的左右邊界,是 pos[x] 中的下標 for (int right = 0; right < pos[x].size(); right++) { while ((pos[x][right] - pos[x][left] + 1) - (right - left + 1) > k) { // 若不符合條件,則開始縮小窗口 left++; } ans = max(ans, right - left + 1); // 更新答案 } } return ans; } };
寫在最後
Cover photo is generated by @ゴリラの素材屋さん, thanks for their work!