[LeetCode] 2831. Find the Longest Equal Subarray

CNoodle發表於2024-05-23

You are given a 0-indexed integer array nums and an integer k.

A subarray is called equal if all of its elements are equal. Note that the empty subarray is an equal subarray.

Return the length of the longest possible equal subarray after deleting at most k elements from nums.

A subarray is a contiguous, possibly empty sequence of elements within an array.

Example 1:
Input: nums = [1,3,2,3,1,3], k = 3
Output: 3
Explanation: It's optimal to delete the elements at index 2 and index 4.
After deleting them, nums becomes equal to [1, 3, 3, 3].
The longest equal subarray starts at i = 1 and ends at j = 3 with length equal to 3.
It can be proven that no longer equal subarrays can be created.

Example 2:
Input: nums = [1,1,2,2,1,1], k = 2
Output: 4
Explanation: It's optimal to delete the elements at index 2 and index 3.
After deleting them, nums becomes equal to [1, 1, 1, 1].
The array itself is an equal subarray, so the answer is 4.
It can be proven that no longer equal subarrays can be created.

Constraints:
1 <= nums.length <= 105
1 <= nums[i] <= nums.length
0 <= k <= nums.length

找出最長等值子陣列。

給你一個下標從 0 開始的整數陣列 nums 和一個整數 k 。

如果子陣列中所有元素都相等,則認為子陣列是一個 等值子陣列 。注意,空陣列是 等值子陣列 。

從 nums 中刪除最多 k 個元素後,返回可能的最長等值子陣列的長度。

子陣列 是陣列中一個連續且可能為空的元素序列。

思路

思路是滑動視窗。題目的最終目標是讓我們找到一個最長的等值子陣列。準確地說與其說是子陣列,不如說是子序列,因為最終題目要求的最長的子陣列裡面的元素的下標並不是連續的。

這裡我們需要一個 hashmap,key 是每個不同元素,value 是一個 queue,儲存的是當前元素在 input 陣列內出現的下標。然後我們開始遍歷 input 陣列,根據遇到的不同元素,把他們的下標都放到各自對應的 queue 中。每當放入一個下標的時候,我們判斷,如果當前這個元素能組成最長的等值子陣列,那麼他第一次出現的下標(假設為 i)和最後一次出現的下標(假設為 j)之間的距離一定要滿足 i + k <= j。如果不滿足這個條件,說明 i 和 j 距離太遠,需要從 i 開始刪除一些元素,直到滿足題目條件為止。

通常情況,i 和 j 之間的距離一定比這個元素實際的個數要大,因為中間夾雜了其他的元素,但是我們要保證其中夾雜的其他元素的個數 <= k。而當前這個相同元素的實際個數 = queue.size()。

複雜度

時間O(n)
空間O(n)

程式碼

Java實現

class Solution {
    public int longestEqualSubarray(List<Integer> nums, int k) {
        HashMap<Integer, Deque<Integer>> map = new HashMap<>();
        int res = 0;
        for (int i = 0; i < nums.size(); i++) {
            int num = nums.get(i);
            if (!map.containsKey(num)) {
                map.put(num, new ArrayDeque<>());
            }
            map.get(num).offerLast(i);
            Deque<Integer> q = map.get(num);
            while (!q.isEmpty() && i - q.peekFirst() + 1 > q.size() + k) {
                q.pollFirst();
            }
            res = Math.max(res, q.size());
        }
        return res;
    }
}

相關文章