堆结构常见题

1、合并K个有序链表

测试链接:合并k个已排序的链表_牛客题霸_牛客网

public class MergeKSortedLists {
    public static void main(String[] args) {

    }
    public static class ListNode() {
        public int val;
        public ListNode next;
    }

    public static ListNode mergeKLists(ArrayList<ListNode> arr) {
        //利用优先级队列创建小根堆
        PriorityQueue<ListNode> heap = new PriorityQueue<>((a, b) -> a.val - b.val);
        for (ListNode head: arr) {
            if (head != null) {
                heap.add(head);
            }
        }
        ListNode newHead = heap.poll();
        ListNode temp = newHead;
        while (!heap.isEmpty()) {
            if(temp.next != null) {
                heap.add(temp.next);
            }     
            temp.next = heap.poll();
            temp = temp.next;
        }
        return newHead;
        
    }
}

2、最多线段重合问题

线段重合_牛客题霸_牛客网 (nowcoder.com)

import java.io.*;
import java.util.*;

// 注意类名必须为 Main, 不要有任何 package xxx 信息

public class Main {
    public static int MAXN = 10001;

    public static int[][] line = new int[MAXN][2];
    //小根堆
    public static PriorityQueue<Integer> heap = new PriorityQueue<>((a, b) -> a-b);
    public static int n;
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StreamTokenizer in = new StreamTokenizer(br);
        PrintWriter out = new PrintWriter(new OutputStreamWriter(System.out));
        while (in.nextToken() != StreamTokenizer.TT_EOF) {
            n = (int) in.nval;
            for (int i = 0; i < n; i++) {
                in.nextToken();
                line[i][0] = (int) in.nval;
                in.nextToken();
                line[i][1] = (int) in.nval;
            }
            out.println(compute());
        }
        out.flush();
        out.close();
        br.close();

    }
    public static int compute() {
        int ans  = 0;;
        heap.clear();    //注意每次在调用compute方法时,要清空堆
        Arrays.sort(line, 0, n, (a,b) -> a[0] - b[0]);
        for (int i = 0; i < n; i++) {
            if (!heap.isEmpty() && line[i][0] >= heap.peek()) {
                heap.poll();
            }
            heap.add(line[i][1]);
            ans = Math.max(ans, heap.size());
        }
        return ans; 
        
    }
}

3、将数组和减半的最少操作次数

2208. 将数组和减半的最少操作次数 - 力扣(LeetCode)

class Solution {
    public int halveArray(int[] nums) {
        //大根堆
        PriorityQueue<Double> heap = new PriorityQueue<>((a, b) -> b.compareTo(a));
        double sum=0;
        for (int i  = 0; i < nums.length; i++) {
            sum += nums[i];
            heap.add((double)nums[i]);
        }
        sum = sum / 2;
        int ans = 0;
        for (double temp = 0, minus = 0; minus < sum; ans++, minus += temp) {
            temp = heap.poll() / 2;
            heap.add(temp); 
        }
        return ans;
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值