[LeetCode] 659. Split Array into Consecutive Subsequences
Given an arraynums
sorted in ascending order, returntrue
if and only if you can split it into 1 or more subsequences such that each subsequence consists of consecutive integersand has length at least 3.
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
Constraints:
1 <= nums.length <= 10000
分割陣列為連續子序列。
給你一個按升序排序的整數陣列 num(可能包含重複數字),請你將它們分割成一個或多個子序列,其中每個子序列都由連續整陣列成且長度至少為 3 。
如果可以完成上述分割,則返回 true ;否則,返回 false 。
來源:力扣(LeetCode)
連結:https://leetcode-cn.com/problems/split-array-into-consecutive-subsequences
著作權歸領釦網路所有。商業轉載請聯絡官方授權,非商業轉載請註明出處。
這道題有兩種思路,一種是貪心,一種涉及到最小堆。我這裡暫時提供一個最小堆的做法。
題目的目標是需要湊若干個長度起碼為3的連續整數子陣列,所以我們一開始肯定是要遍歷input裡的每個數字,並且用hashmap<num, pq>為每個unique的數字建立一個最小堆,意思是記錄每個以 num 為結尾的子陣列的個數。最小堆裡面放的是以num為結尾的子陣列的長度,所以長度最短的子陣列在堆頂。
開始遍歷 input 陣列,當遇到一個數字 num 的時候,放入hashmap,同時去看一下hashmap裡面是否有 num - 1,如果有,需要計算一下以num - 1 為結尾的子陣列的長度是多少,這樣 num 才能被疊加到這個長度上去。如果這個 num 能被疊加,則需要去hashmap裡對num - 1 的value--,直到去掉這個key為止。如果num - 1 不存在,則說明當前的 num 應該是一個子陣列的起點,則直接把他放入hashmap即可。
在遍歷完所有元素之後,我們再次遍歷hashmap的keyset,如果其中有任何一個key的堆頂元素小於3,則說明存在以某個數字為結尾的子陣列,其長度不足3,這不符合題意,返回false。
時間O(nlogn) - 其中O(n)是遍歷每個元素,當子陣列長度有變化的時候,往pq中加入元素的複雜度是O(logn),所以整體還是O(nlogn)
空間O(n)
Java實現
1 class Solution { 2 public boolean isPossible(int[] nums) { 3 // <lastNumber, pq<length>> 4 // 以num為結尾的子陣列的長度 5 // pq是最小堆,最短的子陣列長度在堆頂 6 HashMap<Integer, PriorityQueue<Integer>> map = new HashMap<>(); 7 for (int num : nums) { 8 if (!map.containsKey(num)) { 9 map.put(num, new PriorityQueue<>()); 10 } 11 if (map.containsKey(num - 1)) { 12 int prevLength = map.get(num - 1).poll(); 13 if (map.get(num - 1).isEmpty()) { 14 map.remove(num - 1); 15 } 16 map.get(num).offer(prevLength + 1); 17 } else { 18 map.get(num).offer(1); 19 } 20 } 21 22 for (Integer key : map.keySet()) { 23 if (map.get(key).peek() < 3) { 24 return false; 25 } 26 } 27 return true; 28 } 29 }