- 分割数组为连续子序列
给你一个按升序排序的整数数组 num(可能包含重复数字),请你将它们分割成一个或多个子序列,其中每个子序列都由连续整数组成且长度至少为 3 。
1.哈希表+最小堆
public boolean isPossible(int[] nums) {
Map<Integer,PriorityQueue<Integer>>map=new HashMap<Integer,PriorityQueue<Integer>>();
//哈希表的键是子序列的最后一个数字,值是最小堆(存储的子序列长度)
for(int x :nums) {
if(!map.containsKey(x)) {//初始创建
map.put(x, new PriorityQueue<Integer>());
}
if(map.containsKey(x-1)) {
int preLen=map.get(x-1).poll();//get最小堆再堆顶出队
if(map.get(x-1).isEmpty()) {//如果堆空了
map.remove(x-1);//删除哈希表上的这个节点
}
map.get(x).offer(preLen+1);
//将子序列长度加1之后作为以x结尾的子序列长度
}
else {//如果哈希表中不存在以x-1 结尾的子序列
map.get(x).offer(1);
//则新建一个长度为1 的以x结尾的子序列
}
}
//遍历每个最小堆的堆顶元素判断是否个子序列小于3
Set<Map.Entry<Integer, PriorityQueue<Integer>>> entrySet=map.entrySet();
//键值对映射关系的集合,可使用它对map进行遍历。
for(Map.Entry<Integer, PriorityQueue<Integer>> entry:entrySet) {//遍历映射集合中的每个映射元素
PriorityQueue<Integer>queue=entry.getValue();//取值,即取最小堆
if(queue.peek()<3)
return false;
}
return true;
}
tips:
1.堆(队)操作:
stack.poll();//堆顶出队
stack.offer(1);//1入队
stack.peek();//取堆顶元素的值,不删除元素
2.哈希表:
Map<Integer,PriorityQueue<Integer>> map=new HashMap<Integer,PriorityQueue<Integer>>();
//创建
map.put(x, new PriorityQueue<Integer>());//创建节点
map.remove(x-1);//删除节点
3.遍历哈希表
Set<Map.Entry<Integer, PriorityQueue<Integer>>> entrySet=map.entrySet();
//创建哈希表相关的映射
PriorityQueue<Integer>queue=entry.getKey();//取某个映射的键
PriorityQueue<Integer>queue=entry.getValue();//取某个映射的值
2.贪心法:
public boolean isPossible(int[] nums) {
Map<Integer,Integer> countMap=new HashMap<Integer,Integer>();
Map<Integer,Integer> endMap=new HashMap<Integer,Integer>();
//先计算每个数字出现的次数
for(int num:nums) {
countMap.put(num, countMap.getOrDefault(num, 0)+1);
}
for(int num:nums) {
int count=countMap.getOrDefault(num, 0);
if(count>0) {//还有剩余次数
int countEnd=endMap.getOrDefault(num-1, 0);
if(countEnd>0) {//将x插入x-1队列
countMap.put(num, count-1);
endMap.put(num-1, countEnd-1);
endMap.put(num, endMap.getOrDefault(num, 0)+1);
}
else {//没有x-1,就要重新创建
int count1=countMap.getOrDefault(num+1, 0);
int count2=countMap.getOrDefault(num+2, 0);
if(count1==0||count2==0)//x+1,x+2没有剩余次数,就失败了
return false;
countMap.put(num, count-1);//x的剩余次数少一
countMap.put(num+1, count1-1);//x+1的剩余次数少一
countMap.put(num+2, count2-1);//x+2的剩余次数少一
endMap.put(num+2,endMap.getOrDefault(num+2, 0)+1);//x+2的结尾次数加一
}
}
}
return true;
}