題目連結:
題目意譯:
你被給定一個整數陣列 nums 以及一整數 k。請找到 nums 中所有滿足以下條件的子陣列中子陣列和的最大值:
子陣列的長度為 k,且、
子陣列中所有元素相異。
回傳所有滿足以下條件的子陣列中子陣列和的最大值。如果沒有子陣列滿足條件,則回傳 0。
一個子陣列為一個陣列之中一個連續的非空元素序列。
限制:
1 ≦ k ≦ nums.length ≦ 10 ^ 5
1 ≦ nums[i] ≦ 10 ^ 5
範例測資:
範例 1:
輸入: nums = [1,5,4,2,9,9,9], k = 3
輸出: 15
解釋: nums 中長度為 3 的子陣列為:
- [1,5,4] 其滿足條件,而其總和為 10。
- [5,4,2] 其滿足條件,而其總和為 11。
- [4,2,9] 其滿足條件,而其總和為 15。
- [2,9,9] 其滿足條件,因為元素 9 重複了。
- [9,9,9] 其滿足條件,因為元素 9 重複了。
我們回傳 15,因為它是所有滿足以下條件的子陣列中子陣列和的最大值。
範例 2:
輸入: nums = [4,4,4], k = 3
輸出: 0
解釋: nums 中長度為 3 的子陣列為:
- [4,4,4] 其滿足條件,因為元素 4 重複了。
我們回傳 0,因為沒有子陣列滿足條件。
解題思維:
典型的滑動視窗(Sliding Window)之題型,如
這題。
假設現在我們知道某個長度為 k 且以 nums[i] 作為結尾的子陣列(不一定符合條件)中每一種數字的個數、數字種類數以及數字總和。
而現在我們想要知道「下一個」長度 k 的子陣列,也就是以 nums[i + 1] 作為結尾的子陣列。則我們只需要把數字 nums[i - k + 1] 的個數減去 1,並將數字 nums[i + 1] 的個數加上 1。其中如果 nums[i - k + 1] 的個數歸零的話,則代表數字種類減少了 1;同樣地,如果 nums[i + 1] 的個數從 0 變成 1,則代表數字種類增加了 1。然後我們對總和也做類似的事情。此時便可以看到我們在常數時間內算出了「下一個」子陣列的資訊。
因此可以看到我們一開始只需要從最開始的 k 個數字開始,一直計算「下一個」子陣列的資訊。然後在過程中把符合條件的子陣列之總和挑出來取最大值即是所求。時間複雜度為 O(nums.length),即線性時間。
此次分享到此為止,如有任何更加簡潔的想法或是有說明不清楚之地方,也煩請各位大大撥冗討論。