23--合并k个升序的链表
![](https://i-blog.csdnimg.cn/blog_migrate/8bf099f11a5abeaa2da9ad99b9833cb8.png)
public ListNode mergeKLists(ListNode[] lists) {
if(lists==null||lists.length==0)return null;
PriorityQueue<ListNode> pq = new PriorityQueue<>(new Comparator<ListNode>() {
@Override
public int compare(ListNode l1, ListNode l2) {
return l1.val - l2.val;
}
});
for (int i = 0; i < lists.length; i++) {
ListNode now=lists[i];
while (now!=null){
pq.offer(now);
now=now.next;
}
}
ListNode last;
ListNode res;
//注意链表可能全是空的
if(pq.size()>=1){
last = pq.poll();
res =last;
}else{
return null;
}
while (!pq.isEmpty()) {
ListNode poll = pq.poll();
last.next=poll;
last=poll;
}
last.next=null;
return res;
}
218--天际线问题
![](https://i-blog.csdnimg.cn/blog_migrate/bf67dbdcb9e4ff69dca1bc49b8c8f781.png)
public List<List<Integer>> getSkyline(int[][] bs) {
List<List<Integer>> ans = new ArrayList<>();
// 预处理所有的点,为了方便排序,对于左端点,令高度为负;对于右端点令高度为正
List<int[]> ps = new ArrayList<>();
for (int[] b : bs) {
int l = b[0], r = b[1], h = b[2];
ps.add(new int[]{l, -h});
ps.add(new int[]{r, h});
}
// 先按照横坐标进行排序
// 如果相同的左/右端点,则按照高度进行排序
Collections.sort(ps, (a, b)->{
if (a[0] != b[0]) return a[0] - b[0];
return a[1] - b[1];
});
// 大根堆
PriorityQueue<Integer> q = new PriorityQueue<>((a,b)->b-a);
int prev = 0;//最下面的点是一定会被取到的
q.add(prev);
for (int[] p : ps) {
int point = p[0], height = p[1];
if (height < 0) {
// 如果是左端点,说明存在一条往右延伸的可记录的边,将高度存入优先队列
q.add(-height);
} else {
// 如果是右端点,说明这条边结束了,将当前高度从队列中移除
q.remove(height);
}
// 取出最高高度,如果当前不与前一矩形“上边”延展而来的那些边重合,则可以被记录
int cur = q.peek();
if (cur != prev) {
List<Integer> list = new ArrayList<>();
list.add(point);
list.add(cur);
ans.add(list);
prev = cur;
}
}
return ans;
}
239--滑动窗口的最大值
![](https://i-blog.csdnimg.cn/blog_migrate/03a6f7d6db0c4b0d838038d26c86be77.png)
public int[] maxSlidingWindow(int[] nums, int k) {
int n = nums.length;
PriorityQueue<int[]> pq = new PriorityQueue<>((a, b) -> {
return a[0]!=b[0]?b[0]-a[0]:b[1]-a[1];
});
for (int i = 0; i < k; i++) {
//元素 索引
pq.offer(new int[]{nums[i],i});
}
int[] ans=new int[n-k+1];
ans[0]=pq.peek()[0];
for (int i = k; i <n ; i++) {
pq.offer(new int[]{nums[i],i});
//如果当前最大值的索引已经超出了滑动窗口的左边界,丢出去再也不要了
while (pq.peek()[1]<=i-k){
pq.poll();
}
ans[i-k+1]=pq.peek()[0];
}
return ans;
}
264--数据流的中位数
![](https://i-blog.csdnimg.cn/blog_migrate/efc004e46c30dba5df5d7893f12b06e9.png)
PriorityQueue<Integer> min;
PriorityQueue<Integer> max;
public likou295() {
min = new PriorityQueue<>((a,b)->b-a);
max = new PriorityQueue<>();
}
public void addNum(int num) {
if(min.isEmpty()||num<=min.peek()){
min.offer(num);
//当大队列数小于小队列数2个以上的时候,从小队列补充元素
if(max.size()+1<min.size()){
max.offer(min.poll());
}
}else{
max.offer(num);
//只要小队列的size比大队列的size小就补充元素,这样保证了小队列永远大于等于大队列
if(max.size()>min.size()){
min.offer(max.poll());
}
}
}
public double findMedian() {
if(min.size()>max.size())return min.peek();
else{
return (min.peek()+max.peek())/2.0;
}
}
347--前k个高频元素
![](https://i-blog.csdnimg.cn/blog_migrate/64424e4b1ac6e0efdbcb85dead8b08c6.png)
public int[] topKFrequent(int[] nums, int k) {
PriorityQueue<Map.Entry<Integer, Integer>> queue = new PriorityQueue<>((a,b)->b.getValue()-a.getValue());
int[] res=new int[k];
HashMap<Integer, Integer> map = new HashMap<>();
//使用哈希表计数
for (int i = 0; i < nums.length; i++) {
map.put(nums[i],map.getOrDefault(nums[i],0)+1);
}
//遍历哈希表
Iterator<Map.Entry<Integer, Integer>> iterator = map.entrySet().iterator();
while (iterator.hasNext()){
queue.offer(iterator.next());
}
int count=0;
while (count!=k){
Map.Entry<Integer, Integer> poll = queue.poll();
res[count]=poll.getKey();
count++;
}
return res;
}
373--查找和最小的k对数字
![](https://i-blog.csdnimg.cn/blog_migrate/3eb46fcabc1d571939649781bceabc45.png)
public List<List<Integer>> kSmallestPairs(int[] nums1, int[] nums2, int k) {
//大顶堆
PriorityQueue<List<Integer>> queue = new PriorityQueue<>(k, (o1, o2)->{
return (o2.get(0) + o2.get(1)) - (o1.get(0) + o1.get(1));
});
//取最小值是为了防止两个数组一个比较少的时候【1】 【1,2,3】
for(int i = 0; i < Math.min(nums1.length, k); i++){
for(int j = 0; j < Math.min(nums2.length, k); j++){
if(queue.size() < k) {
List<Integer> pair = new ArrayList<>();
pair.add(nums1[i]);
pair.add(nums2[j]);
queue.add(pair);
}else {
int top = queue.peek().get(0) + queue.peek().get(1);
//大于K就出队列
if(top > nums1[i]+nums2[j]){
List<Integer> pair = new ArrayList<>();
queue.poll();
pair.add(nums1[i]);
pair.add(nums2[j]);
queue.add(pair);
}
}
}
}
List<List<Integer>> res = new LinkedList<>();
for(int i =0; i < k && !queue.isEmpty(); i++){
res.add(queue.poll());
}
return res;
}
378--有序矩阵中第k小的元素
![](https://i-blog.csdnimg.cn/blog_migrate/d19c92d1005cdca90ab5696a2a5adc4b.png)
public int kthSmallest(int[][] matrix, int k) {
PriorityQueue<Integer> queue = new PriorityQueue<>();
int l = matrix[0].length;
for (int i = 0; i < matrix.length; i++) {
for (int j = 0; j < l; j++) {
queue.offer(matrix[i][j]);
}
}
int res=Integer.MAX_VALUE;
while (k!=0){
res=queue.poll();
k--;
}
return res;
}
658--找到k个最接近的元素
![](https://i-blog.csdnimg.cn/blog_migrate/d6dee30b9d9f1abe7bdb4d74c390a16e.png)
public List<Integer> findClosestElements(int[] arr, int k, int x) {
PriorityQueue<Integer> queue = new PriorityQueue<>((a,b)->{
return Math.abs(a-x)==Math.abs(b-x)?a-b:Math.abs(a-x)-Math.abs(b-x);
});
for (int i : arr) {
queue.offer(i);
}
List<Integer> res=new ArrayList<>();
while (k--!=0&&!queue.isEmpty()){
res.add(queue.poll());
}
Collections.sort(res);
return res;
}