package com.example.lettcode.dailyexercises;
import java.util.HashMap;
import java.util.Map;
/**
* @Class IsPossible
* @Description 659 分割数组为连续子序列
* 给你一个按升序排序的整数数组 num(可能包含重复数字),请你将它们分割成一个或多个子序列,其中每个子序列都由连续整数组成且长度至少为 3 。
* 如果可以完成上述分割,则返回 true ;否则,返回 false 。
* <p>
* 示例 1:
* 输入: [1,2,3,3,4,5]
* 输出: True
* 解释:
* 你可以分割出这样两个连续子序列 :
* 1, 2, 3
* 3, 4, 5
* <p>
* 示例 2:
* 输入: [1,2,3,3,4,4,5,5]
* 输出: True
* 解释:
* 你可以分割出这样两个连续子序列 :
* 1, 2, 3, 4, 5
* 3, 4, 5
* <p>
* 示例 3:
* 输入: [1,2,3,4,4,5]
* 输出: False
* <p>
* 提示:
* 输入的数组长度范围为 [1, 10000]
* Related Topics 堆 贪心算法
* @Author
* @Date 2020/12/4
**/
public class IsPossible {
public static boolean isPossible(int[] nums) {
if (nums == null || nums.length < 3) return false;
Map<Integer, Integer> integerMap = new HashMap<>();
// 保存每个整数出现的次数
for (int num : nums) {
integerMap.put(num, integerMap.getOrDefault(num, 0) + 1);
}
for (int num : nums) {
int subNum = 0; // 子数组的个数
int p = 1; // 表示当前元素出现的总次数
int next = num; // 下一个连续整数
// 判断上一个元素出现的次数是否超过下一个元素出现的次数,不超过则说明至少有一个子序列是不会同时包含两个元素的
while (integerMap.getOrDefault(next, 0) >= p) {
p = integerMap.get(next);
integerMap.put(next, p - 1);
subNum++;
next++;
}
if (subNum > 0 && subNum < 3) return false;
}
return true;
}
}
// 测试用例
public static void main(String[] args) {
int[] nums = new int[]{1, 2, 3, 3, 4, 5};
boolean ans = isPossible(nums);
System.out.println("IsPossible demo01 result:" + ans);
nums = new int[]{1, 2, 3, 3, 4, 4, 5, 5};
ans = isPossible(nums);
System.out.println("IsPossible demo02 result:" + ans);
nums = new int[]{1, 2, 3, 3, 4, 5};
ans = isPossible(nums);
System.out.println("IsPossible demo03 result:" + ans);
nums = new int[]{1, 2, 4, 5, 8, 9};
ans = isPossible(nums);
System.out.println("IsPossible demo04 result:" + ans);
nums = new int[]{1,2,3,4,4,5};
ans = isPossible(nums);
System.out.println("IsPossible demo05 result:" + ans);
}