1. 程式人生 > >[LeetCode] Split Array into Consecutive Subsequences 將陣列分割成連續子序列

[LeetCode] Split Array into Consecutive Subsequences 將陣列分割成連續子序列

You are given an integer array sorted in ascending order (may contain duplicates), you need to split them into several subsequences, where each subsequences consist of at least 3 consecutive integers. Return whether you can make such a split.

Example 1:

Input: [1,2,3,3,4,5]
Output: True
Explanation:
You can split them into two consecutive subsequences : 
1, 2, 3
3, 4, 5

Example 2:

Input: [1,2,3,3,4,4,5,5]
Output: True
Explanation:
You can split them into two consecutive subsequences : 
1, 2, 3, 4, 5
3, 4, 5

Example 3:

Input: [1,2,3,4,4,5]
Output: False

Note:

  1. The length of the input is in range of [1, 10000]

博主第一眼看到這題,心想,我去,這不就是打牌麼,什麼挖坑,拐3,紅桃4啊,3個起連,有時候排組合的好,就不用劃單兒。這道題讓我們將陣列分割成多個連續遞增的子序列,注意這裡可能會產生歧義,實際上應該是分割成一個或多個連續遞增的子序列,因為[1,2,3,4,5]也是正確的解。這道題就用貪婪解法就可以了,我們使用兩個雜湊表map,第一個map用來建立數字和其出現次數之間的對映freq,第二個用來建立可以加在某個連續子序列後的數字及其可以出現的次數之間的對映need。對於第二個map,舉個例子來說,就是假如有個連,[1,2,3],那麼後面可以加上4,所以就建立4的對映。這樣我們首先遍歷一遍陣列,統計每個數字出現的頻率,然後我們開始遍歷陣列,對於每個遍歷到的數字,首先看其當前出現的次數,如果為0,則繼續迴圈;如果need中存在這個數字的非0對映,那麼表示當前的數字可以加到某個連的末尾,我們將當前數字的對映值自減1,然後將下一個連續數字的對映值加1,因為當[1,2,3]連上4後變成[1,2,3,4]之後,就可以連上5了;如果不能連到其他子序列後面,我們來看其是否可以成為新的子序列的起點,可以通過看後面兩個數字的對映值是否大於0,都大於0的話,說明可以組成3連兒,於是將後面兩個數字的對映值都自減1,還有由於組成了3連兒,在need中將末尾的下一位數字的對映值自增1;如果上面情況都不滿足,說明該數字是單牌,只能劃單兒,直接返回false。最後別忘了將當前數字的freq對映值自減1。退出for迴圈後返回true,參見程式碼如下: