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:

  1. 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 }

 

posted @ 2017-10-26 09:57  Dylan_Java_NYC  阅读(570)  评论(0编辑  收藏  举报