LeetCode Split Array into Consecutive Subsequences
原题链接在这里:https://leetcode.com/problems/split-array-into-consecutive-subsequences/description/
题目:
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,
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:
- The length of the input is in range of [1, 10000]
题解:
对于当前distinct数字 cur, 保存以它结尾的长度1, 2, 和>=3的subsequences数目. count是cur的frequency.
当前个distinct值pre, 如果pre+1 != cur, 说明cur只能用来起头新的subsequence, 但如果前面的噗p1或p2不为0, 说明前面的只能组成长度为1或2的subsequence, return false.
如果pre+1 == cur, 说明cur可以用来append前面的subsequence.
前面长度为1的subsequence个数就是现在长度为2的subsequence个数. c2=p1.
前面长度为2的subsequence个数就是现在长度为3的subsequence个数. 若前面有长度大于3的, 这里可以继续append组成长度大于4的. 但前提是先满足前面长度1和2后剩下的. c3 = p2 + Math.min(p3, count-(p1+p2)).
也可以开始组成新的长度为1的subsequence, 前提是前面用剩下的. c1 = Math.max(0, count-(p1+p2+p3)).
Time Complexity: O(nums.length). Space: O(1).
AC Java:
1 class Solution { 2 public boolean isPossible(int[] nums) { 3 int pre = Integer.MIN_VALUE; 4 int p1 = 0; 5 int p2 = 0; 6 int p3 = 0; 7 int cur = 0; 8 int c1 = 0; 9 int c2 = 0; 10 int c3 = 0; 11 int count = 0; 12 13 int i = 0; 14 while(i<nums.length){ 15 for(cur = nums[i], count = 0; i<nums.length && cur==nums[i]; i++){ 16 count++; 17 } 18 19 if(cur != pre+1){ 20 if(p1!=0 || p2!=0){ 21 return false; 22 } 23 24 c1 = count; 25 c2 = 0; 26 c3 = 0; 27 }else{ 28 if(count < p1+p2){ 29 return false; 30 } 31 32 c1 = Math.max(0, count-(p1+p2+p3)); 33 c2 = p1; 34 c3 = p2 + Math.min(p3, count-(p1+p2)); 35 } 36 37 pre=cur; 38 p1=c1; 39 p2=c2; 40 p3=c3; 41 } 42 return p1==0 && p2==0; 43 } 44 }
如果给出的nums不是sorted的, 则可先统计数字的frequency.
再扫一遍nums array, 对于每个数字要么能承上, 要么能启下.
都不能就return false.
Time Complexity: O(nums.length).
Space: O(nums.length).
AC Java:
1 class Solution { 2 public boolean isPossible(int[] nums) { 3 HashMap<Integer, Integer> hm = new HashMap<Integer, Integer>(); 4 for(int num : nums){ 5 hm.put(num, hm.getOrDefault(num, 0)+1); 6 } 7 8 HashMap<Integer, Integer> append = new HashMap<Integer, Integer>(); 9 for(int num : nums){ 10 if(hm.get(num) == 0){ 11 continue; 12 } 13 14 if(append.getOrDefault(num, 0) > 0){ 15 append.put(num, append.get(num)-1); 16 append.put(num+1, append.getOrDefault(num+1, 0)+1); 17 }else if(hm.getOrDefault(num+1, 0) > 0 && hm.getOrDefault(num+2, 0) > 0){ 18 hm.put(num+1, hm.get(num+1)-1); 19 hm.put(num+2, hm.get(num+2)-1); 20 append.put(num+3, append.getOrDefault(num+3, 0)+1); 21 }else{ 22 return false; 23 } 24 25 hm.put(num, hm.get(num)-1); 26 } 27 28 return true; 29 } 30 }