IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 数据结构与算法 -> 算法:堆相关题目 -> 正文阅读

[数据结构与算法]算法:堆相关题目

堆相关题目

一、实现大顶堆、小顶堆

1.1 小顶堆

/**
 * @Date 2021/10/17
 * @Author lifei
 */
public class MinHeap<T extends Comparable<T>> {

    private int capacity;
    private T[] a;
    private int N;

    public MinHeap(int capacity) {
        this.capacity = capacity;
        a = (T[]) new Comparable[capacity+1];
    }

    public int size() {
        return N;
    }

    public boolean isEmpty() {
        return size()==0;
    }

    public boolean isFull() {
        return size()==capacity;
    }

    public void push(T t) {
        if (isFull()) return;
        a[++N] = t;
        swim(N);
    }

    public T delMin() {
        if (isEmpty()) return null;
        T t = a[1];
        exch(1, N--);
        a[N+1] = null;
        sink(1);
        return t;
    }

    private void sink(int k) {
        while (2*k<=N) {
            int j = 2*k;
            if (j<N && less(j+1, j)) j++;
            if (less(k, j)) break;
            exch(j, k);
            k = j;
        }
    }

    private void swim(int k) {
        while (k>1 && less(k, k/2)) {
            exch(k, k/2);
            k = k/2;
        }
    }

    private void exch(int i, int j) {
        T t = a[i];
        a[i] = a[j];
        a[j] = t;
    }

    private boolean less(int i, int j) {
        return a[i].compareTo(a[j])<0;
    }

    public static void main(String[] args) {
        MinHeap<Integer> heap = new MinHeap<>(6);
        heap.push(3);
        heap.push(5);
        heap.push(1);
        heap.push(0);
        heap.push(9);
        heap.push(2);
        while (!heap.isEmpty()) {
            System.out.print(heap.delMin() + ", ");
        }
        System.out.println();
    }
}

1.2 大顶堆

/**
 * @Date 2021/10/17
 * @Author lifei
 */
public class MaxHeap<T extends Comparable<T>> {

    private int capacity;
    private T[] a;
    private int N;

    public MaxHeap(int capacity) {
        this.capacity = capacity;
        a = (T[]) new Comparable[capacity+1];
    }

    public int size() {
        return N;
    }

    public boolean isEmpty() {
        return size()==0;
    }

    public boolean isFull() {
        return size()==capacity;
    }

    public void push(T t) {
        if (isFull()) return;
        a[++N] = t;
        swim(N);
    }

    public T delMax() {
        if (isEmpty()) return null;
        T t = a[1];
        exch(1, N--);
        a[N+1] = null;
        sink(1);
        return t;
    }

    private void sink(int k) {
        while (2*k<=N) {
            int j = 2*k;
            if (j<N && less(j, j+1)) j++;
            if (less(j, k)) break;
            exch(j, k);
            k = j;
        }
    }

    private void swim(int k) {
        while (k>1 && less(k/2, k)) {
            exch(k, k/2);
            k = k/2;
        }
    }

    private void exch(int i, int j) {
        T t = a[i];
        a[i] = a[j];
        a[j] = t;
    }

    private boolean less(int i, int j) {
        return a[i].compareTo(a[j])<0;
    }

    public static void main(String[] args) {
        MaxHeap<Integer> heap = new MaxHeap<>(6);
        heap.push(3);
        heap.push(5);
        heap.push(1);
        heap.push(0);
        heap.push(9);
        heap.push(2);
        while (!heap.isEmpty()) {
            System.out.print(heap.delMax() + ", ");
        }
        System.out.println();
    }
}

二、堆排序

核心方法:sink

public class HeapSort {

    public static void main(String[] args) {
        Integer[] a = {9, 8,4, 1,2, 9, 8,4, 1,2};
        System.out.println(Arrays.toString(a));
        HeapSort.sort(a);
        System.out.println(Arrays.toString(a));
    }

    public static void sort(Comparable[] a) {
        if (a==null || a.length<=1) return;
        int N = a.length;
        for (int k=N/2; k>=1; k--) {
            sink(a, k, N);
        }
        while (N>=1) {
            exch(a, 1, N--);
            sink(a, 1, N);
        }
    }

    private static void sink(Comparable[] a, int k, int N) {
        while (k*2<=N) {
            int j = k*2;
            if (j<N && less(a, j, j+1)) j++;
            if (less(a, j, k)) break;
            exch(a, k, j);
            k = j;
        }
    }

    private static void exch(Comparable[] a, int i, int j) {
        Comparable t = a[i-1];
        a[i-1] = a[j-1];
        a[j-1] = t;
    }

    private static boolean less(Comparable[] a, int i, int j) {
        return a[i-1].compareTo(a[j-1])<0;
    }
}

三、剑指 Offer 40. 最小的k个数

3.1 解法一:排序后取值

    public int[] getLeastNumbers(int[] arr, int k) {
        Arrays.sort(arr);
        int[] res = new int[k];
        for (int i=0; i<k; i++) {
            res[i] = arr[i];
        }
        return res;
    }

3.2 解法二:借助堆排序解决

    public int[] getLeastNumbers(int[] arr, int k) {
        int N = arr.length;
        if (N<1) return new int[0];
        for (int i=N/2; i>=1; i--) {
            sink(arr, i, N);
        }
        int[] res = new int[k];
        int j = 0;
        while (j<k) {
            res[j++] = arr[0];
            exch(arr, 1, N--);
            sink(arr, 1, N);
        }
        return res;
    }

    private void sink(int[] arr, int k, int N) {
        while (k*2<=N) {
            int j = k * 2;
            if (j<N && less(arr, j+1, j)) j++;
            if (less(arr, k, j)) break;
            exch(arr, j, k);
            k = j;
        }
    }

    private boolean less(int[] arr, int i, int j) {
        return arr[i-1]<arr[j-1];
    }

    private void exch(int[] arr, int i, int j) {
        int t = arr[i-1];
        arr[i-1] = arr[j-1];
        arr[j-1] = t;
    }

四、239. 滑动窗口最大值

还是使用队列比较好做

    public int[] maxSlidingWindow(int[] nums, int k) {
        Deque<Integer> deque = new LinkedList<>();
        int[] res = new int[nums.length-k+1];
        for (int i=0; i<nums.length; i++) {
            while (!deque.isEmpty() && nums[deque.peekLast()]<nums[i]) {
                deque.removeLast();
            }
            deque.addLast(i);
            int w = i - k + 1;
            if (deque.peek()<w) {
                deque.pop();
            }
            if (w>=0) {
                res[w] = nums[deque.peek()];
            }
        }
        return res;
    }

五、剑指 Offer 49. 丑数

解法一:使用优先级队列和Set

    public int nthUglyNumber(int n) {
        int[] a = {2, 3, 5};
        PriorityQueue<Long> queue = new PriorityQueue<>();
        Set<Long> visited = new HashSet<>();
        queue.add(1l);
        visited.add(1l);
        long res = 1;
        for (int i=1; i<=n; i++) {
            res = queue.poll();
            for (int k=0; k<a.length; k++) {
                if (!visited.contains(a[k]*res)) {
                    visited.add(a[k]*res);
                    queue.add(a[k]*res);
                }
            }
        }
        return (int)res;
    }

解法二:动态规划

    public int nthUglyNumber(int n) {
        int[] dp = new int[n+1];
        dp[1]= 1;
        int p2 = 1, p3 = 1, p5 = 1;
        for (int i=2; i<=n; i++) {
            int num2 = dp[p2] * 2, num3 = dp[p3] * 3, num5 = dp[p5] * 5;
            dp[i] = Math.min(Math.min(num2, num3), num5);
            // 解决重复问题
            if (dp[i]==num2) {
                p2++;
            }
            if (dp[i]==num3) {
                p3++;
            }
            if (dp[i]==num5){
                p5++;
            }
        }
        return dp[n];
    }

六、347. 前 K 个高频元素

6.1 解法一:使用大顶堆,sink、swim

    public int[] topKFrequent(int[] nums, int k) {
        Map<Integer, Integer> map =new HashMap<>();
        for (int i=0; i<nums.length; i++) {
            map.put(nums[i], map.getOrDefault(nums[i], 0)+1);
        }
        int[] a = new int[map.size()+1];
        int N = 0;
        for (Map.Entry<Integer, Integer> entry: map.entrySet()) {
            a[++N] = entry.getKey();
            swim(a, N, map);
        }
        int[] res = new int[k];
        for (int i=0; i<k; i++) {
            res[i] = a[1];
            exch(a, 1, N--);
            sink(a, 1, N, map);
        }
        return res;
    }

    private void sink(int[] a, int k, int N, Map<Integer, Integer> map) {
        while (k*2<=N) {
            int j= k * 2;
            if (j<N && less(j, j+1, map, a)) j++;
            if (less(j, k, map, a)) break;
            exch(a, j, k);
            k = j;
        }
    }

    private void swim(int[] a, int k, Map<Integer, Integer> map) {
        while (k>1 && less(k/2, k, map, a)) {
            exch(a, k, k/2);
            k = k/2;
        }
    }

    private void exch(int[] a, int i, int j) {
        int t = a[i];
        a[i] = a[j];
        a[j] = t;
    }

    private boolean less(int i, int j, Map<Integer, Integer> map, int[] a) {
        return map.get(a[i])<map.get(a[j]);
    }
  数据结构与算法 最新文章
【力扣106】 从中序与后续遍历序列构造二叉
leetcode 322 零钱兑换
哈希的应用:海量数据处理
动态规划|最短Hamilton路径
华为机试_HJ41 称砝码【中等】【menset】【
【C与数据结构】——寒假提高每日练习Day1
基础算法——堆排序
2023王道数据结构线性表--单链表课后习题部
LeetCode 之 反转链表的一部分
【题解】lintcode必刷50题<有效的括号序列
上一篇文章      下一篇文章      查看所有文章
加:2021-10-18 17:38:08  更:2021-10-18 17:39:06 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/26 7:44:52-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码