题目描述:
给你一个按升序排序的整数数组 num(可能包含重复数字),请你将它们分割成一个或多个子序列,其中每个子序列都由连续整数组成且长度至少为 3 。如果可以完成上述分割,则返回 true ;否则,返回 false 。
示例1
输入: [1,2,3,3,4,5]
输出: True
解释:
你可以分割出这样两个连续子序列 :
1, 2, 3
3, 4, 5
示例2
输入: [1,2,3,3,4,4,5,5]
输出: True
解释:
你可以分割出这样两个连续子序列 :
1, 2, 3, 4, 5
3, 4, 5
示例3
输入: [1,2,3,4,4,5]
输出: False
我的答案:(本答案无法通过测试,但是提供一种可行思路)
首先来一张图解:
核心的求解思路:将重复的数值堆叠起来(计数),由上层开始进行子数列的划分,直到以下情况终止:1.下一个数字不连续;2.下一个数字只剩一个且当前处于重叠区(图中蓝线的终止情况);在每次终止时进行判断:如果子数列长度小于3,则返回false,如果长度大于3则继续进行下一个子数列的划分。
class Solution {
public boolean isPossible(int[] nums) {
if(nums.length<3) return false;
ArrayList<Node> numbers = new ArrayList<>();
int j = 0;
for (int i = 0; i < nums.length; i++){
if(i == nums.length-1){
numbers.add(new Node(nums[i], j+1));
continue;
}
if(nums[i]==nums[i+1]){
++j;
}else{
numbers.add(new Node(nums[i], j+1));
j = 0;
}
}
int i = 0, k = 0;
j = 0;
int flag = 0;
while (numbers.get(i).times!=0) {
if(k==1 && !(numbers.get(i).times>1)){
if (flag < 3) return false;
flag = 0;
i = j;
k = 0;
continue;
}
if(i==numbers.size()-1){
if(numbers.get(i).times>0) ++flag;
if (flag < 3) return false;
numbers.get(i).times = numbers.get(i).times - 1;
flag = 0;
i = j;
k = 0;
continue;
}
if (numbers.get(i).times > 1) {
if (k == 0) {
k = 1;
j = i;
}
numbers.get(i).times = numbers.get(i).times - 1;
++flag;
if(numbers.get(i + 1).num - numbers.get(i).num != 1){
if (flag < 3) return false;
flag = 0;
i = j;
k = 0;
continue;
}else{
++i;
continue;
}
}
if (numbers.get(i + 1).num - numbers.get(i).num == 1) {
numbers.get(i).times = numbers.get(i).times - 1;
++flag;
++i;
} else {
if (flag+1 < 3) return false;
flag = 0;
i = j;
k = 0;
}
}
return true;
}
public class Node{
int num;
int times;
public Node(int num, int times) {
this.num = num;
this.times = times;
}
}
}
大神答案:贪心算法
大神答案