面试经典150题——堆

news/2025/2/19 10:16:23

文章目录

  • 1、数组中的第K个最大元素
    • 1.1 题目链接
    • 1.2 题目描述
    • 1.3 解题代码
    • 1.4 解题思路
  • 2、IPO
    • 2.1 题目链接
    • 2.2 题目描述
    • 2.3 解题代码
    • 2.4 解题思路
  • 3、查找和最小的 K 对数字
    • 3.1 题目链接
    • 3.2 题目描述
    • 3.3 解题代码
    • 3.4 解题思路
  • 4、数据流的中位数
    • 4.1 题目链接
    • 4.2 题目描述
    • 4.3 解题代码
    • 4.4 解题思路


1、数组中的第K个最大元素

1.1 题目链接

点击跳转到题目位置

1.2 题目描述

给定整数数组 nums 和整数 k,请返回数组中第 k 个最大的元素。

请注意,你需要找的是数组排序后的第 k 个最大的元素,而不是第 k 个不同的元素。

你必须设计并实现时间复杂度为 O(n) 的算法解决此问题。

提示:

  • 1 <= k <= nums.length <= 105
  • -104 <= nums[i] <= 104

1.3 解题代码

class Solution {
    
    public int findKthLargest(int[] nums, int k) {
        int heapSize = nums.length;
        bulidMaxHeap(nums, heapSize);
        for(int i = nums.length - 1; i >= nums.length - k + 1; --i){
            swap(nums, 0, i);
            --heapSize;
            maxHeapipy(nums, 0, heapSize);
        }
        return nums[0];
    }

    public void bulidMaxHeap(int[] nums, int heapSize){
        for(int i =  heapSize / 2 - 1; i >= 0; --i){
            maxHeapipy(nums, i, heapSize);
        }
    }

    public void maxHeapipy(int[] nums, int i, int heapSize){
        int l = i * 2 + 1, r = i * 2 + 2, largest = i;
        if(l < heapSize && nums[l] > nums[largest]){
            largest = l;
        }
        if(r < heapSize && nums[r] > nums[largest]){
            largest = r;
        }
        if(largest != i){
            swap(nums, i, largest);
            maxHeapipy(nums, largest, heapSize);
        }
    }

    public void swap(int[] nums, int i, int j){
        int temp = nums[i];
        nums[i] = nums[j];
        nums[j] = temp;
    }
}

1.4 解题思路

  1. 建立大根堆。

2、IPO

2.1 题目链接

点击跳转到题目位置

2.2 题目描述

假设 力扣(LeetCode)即将开始 IPO 。为了以更高的价格将股票卖给风险投资公司,力扣 希望在 IPO 之前开展一些项目以增加其资本。 由于资源有限,它只能在 IPO 之前完成最多 k 个不同的项目。帮助 力扣 设计完成最多 k 个不同项目后得到最大总资本的方式。

给你 n 个项目。对于每个项目 i ,它都有一个纯利润 profits[i] ,和启动该项目需要的最小资本 capital[i] 。

最初,你的资本为 w 。当你完成一个项目时,你将获得纯利润,且利润将被添加到你的总资本中。

总而言之,从给定项目中选择 最多 k 个不同项目的列表,以 最大化最终资本 ,并输出最终可获得的最多资本。

答案保证在 32 位有符号整数范围内。

提示:

  • 1 <= k <= 105
  • 0 <= w <= 109
  • n == profits.length
  • n == capital.length
  • 1 <= n <= 105
  • 0 <= profits[i] <= 104
  • 0 <= capital[i] <= 109

2.3 解题代码

class Solution {
    public int findMaximizedCapital(int k, int w, int[] profits, int[] capital) {
        int res = w;
        int n = profits.length;
        int[][] nums = new int[n][2];
        for(int i = 0; i < n; ++i){
            nums[i][0] = profits[i];
            nums[i][1] = capital[i];
        }
        Arrays.sort(nums, (a, b) -> a[1] - b[1]);
        PriorityQueue<Integer> pq = new PriorityQueue<>((x , y) -> y - x);
        int idx = 0;
        while(idx < n && w >= nums[idx][1]){
            pq.offer(nums[idx][0]);
            idx++;
        }
        while(k > 0 && !pq.isEmpty()){
            k--;
            int num = pq.poll();
            res += num;
            w += num;
            while(idx < n && w >= nums[idx][1]){
                pq.offer(nums[idx][0]);
                idx++;
            }
        }
        return res;
    }
}

2.4 解题思路

  1. 创建一个二维数组,存入每一个项目的利润和成本。并且将该二维数组按照成本非递减进行排序。
  2. 创建一个大根堆,利润高的项目在堆顶。
  3. 初始化最终利润为本金,每次取项目前现将满足条件(成本小于等于当前记录的最终利润)的项目放入大根堆中,每次取项目取栈顶即可。

3、查找和最小的 K 对数字

3.1 题目链接

点击跳转到题目位置

3.2 题目描述

给定两个以 非递减顺序排列 的整数数组 nums1 和 nums2 , 以及一个整数 k 。

定义一对值 (u,v),其中第一个元素来自 nums1,第二个元素来自 nums2 。

请找到和最小的 k 个数对 (u1,v1), (u2,v2) … (uk,vk) 。

提示:

  • 1 <= nums1.length, nums2.length <= 105
  • -109 <= nums1[i], nums2[i] <= 109
  • nums1 和 nums2 均为 升序排列
  • 1 <= k <= 104
  • k <= nums1.length * nums2.length

3.3 解题代码

class Solution {
    public List<List<Integer>> kSmallestPairs(int[] nums1, int[] nums2, int k) {
        List<List<Integer>> res = new ArrayList<>();
        PriorityQueue<int []> pq = new PriorityQueue<>(k, (o1, o2)->{
            return nums1[o1[0]] + nums2[o1[1]] - nums1[o2[0]] - nums2[o2[1]];
        });
        int m = nums1.length;
        int n = nums2.length;
        for(int i = 0; i < Math.min(m, k); ++i){
            pq.offer(new int[]{i, 0});
        }
        while(!pq.isEmpty() && k > 0){
            k--;
            int[] idxPair = pq.poll();
            List list = new ArrayList<>();
            list.add(nums1[idxPair[0]]);
            list.add(nums2[idxPair[1]]);
            res.add(list);
            if(idxPair[1] < n - 1){
                pq.offer(new int[]{idxPair[0], idxPair[1] + 1});
            }
        }
        return res;
    }
}

3.4 解题思路

  1. 贪心+优先队列。
  2. 优先队列以小根堆的形式,存放的数对下标,其对应的数对值最小的则在堆顶。设m为nums1数组的长度,n为nums2数组的长度,则先取的数对,第一个元素为nums1中前k(m)个元素(如果不足k个取m个)。
  3. 然后开始根据优先队列中的堆顶来取元素,记堆顶元素下标对为(x, y),则可能比堆里面的数小的数对中,最小的是{nums1[x], nums2[y + 1]} (只要y小于n - 1)。

4、数据流的中位数

4.1 题目链接

点击跳转到题目位置

4.2 题目描述

中位数是有序整数列表中的中间值。如果列表的大小是偶数,则没有中间值,中位数是两个中间值的平均值。

  • 例如 arr = [2,3,4] 的中位数是 3 。
  • 例如 arr = [2,3] 的中位数是 (2 + 3) / 2 = 2.5 。
  • 实现 MedianFinder 类:

实现 MedianFinder 类:

  • MedianFinder() 初始化 MedianFinder 对象。
  • void addNum(int num) 将数据流中的整数 num 添加到数据结构中。
  • double findMedian() 返回到目前为止所有元素的中位数。与实际答案相差 10-5 以内的答案将被接受。

提示:

  • -105 <= num <= 105
  • 在调用 findMedian 之前,数据结构中至少有一个元素
  • 最多 5 * 104 次调用 addNum 和 findMedian

4.3 解题代码

class MedianFinder {
    PriorityQueue<Integer> maxQueue;// 大根堆
    PriorityQueue<Integer> minQueue;// 小根堆
    public MedianFinder() {
        // 保证大根堆中的元素数量大于等于小根堆中的元素数量
        maxQueue = new PriorityQueue<>(Comparator.reverseOrder());// 大根堆
        minQueue = new PriorityQueue<>();// 小根堆
    }
    
    public void addNum(int num) {
        if(maxQueue.isEmpty() || num <= maxQueue.peek()){
            maxQueue.offer(num);
            while(maxQueue.size() > minQueue.size() + 1){
                minQueue.offer(maxQueue.poll());
            }
        } else{
            minQueue.offer(num);
            while(maxQueue.size() < minQueue.size()){
                maxQueue.offer(minQueue.poll());
            }
        }
    }
    
    public double findMedian() {
        if(maxQueue.size() > minQueue.size()){// 优先队列中元素总和为
            return maxQueue.peek();
        } else{
            return (maxQueue.peek() + minQueue.peek()) / 2.0;
        }
    }
}

/**
 * Your MedianFinder object will be instantiated and called as such:
 * MedianFinder obj = new MedianFinder();
 * obj.addNum(num);
 * double param_2 = obj.findMedian();
 */

4.4 解题思路

  1. 用优先队列维持两个堆,一个为大根堆,一个为小根堆,保证大根堆中的元素数量大于等于小根堆中元素的数量,并且最多只能多出一个。
  2. 建两个堆是为了保证,大根堆中的元素都小于等于小根堆中的元素,如果元素总数为奇数的话,中位数就是大根堆的堆顶元素,如果为偶数的话,则是大根堆和小根堆堆顶的元素和取平均值。
  3. 对于插入数字而言,如果插入时大根堆为空或者插入的数小于等于大根堆的堆顶,则插入小根堆中(不影响两个堆的堆顶),此时如果大根堆的堆顶元素数量大于小根堆堆顶的元素数 + 1,则将大根堆的堆顶插入到小根堆中;如果插入时插入的数大于大根堆的堆顶,则插入小根堆中,如果大根堆中的元素个数小于小根堆中的元素个数,则将小根堆的堆顶插入进入大根堆中。

http://www.niftyadmin.cn/n/5852674.html

相关文章

KubeSphere 和 K8s 高可用集群离线部署全攻略

本文首发&#xff1a;运维有术&#xff0c;作者术哥。 今天&#xff0c;我们将一起探索如何在离线环境中部署 K8s v1.30.6 和 KubeSphere v4.1.2 高可用集群。对于离线环境的镜像仓库管理&#xff0c;官方推荐使用 Harbor 作为镜像仓库管理工具&#xff0c;它为企业级用户提供…

深入解析 vLLM:高性能 LLM 服务框架的架构之美(上)

修改内容时间2.4.1处理请求的流程&#xff0c;引用更好的流程图2025.02.11首发2025.02.08 1. vLLM 整体代码架构 1.1 vLLM 的设计目标与特点 vLLM 是一个高性能的大语言模型服务框架。在大语言模型日益普及的今天&#xff0c;如何高效地提供推理服务成为一个重要挑战。传统的…

jenkins服务启动-排错

服务状态为active (exited) 且进程不在 查看/etc/rc.d/init.d/jenkins配置 获取配置参数 [rootfy-jenkins-prod jenkins]# cat /etc/rc.d/init.d/jenkins | grep -v #JENKINS_WAR"/usr/lib/jenkins/jenkins.war" test -r "$JENKINS_WAR" || { echo "…

CTFSHOW-WEB入门-PHP特性109-115

题目&#xff1a;web 109 1. 题目&#xff1a; 2. 解题思路&#xff1a;题目要求获得两个参数&#xff0c;v1 v2&#xff0c;if语句中的意思是要求两个参数都包含字母&#xff0c;条件满足的话&#xff0c;执行 echo new 类名&#xff08;方法&#xff08;&#xff09;&#xf…

untiy3D 让角色动起来,角色动画的使用

1.untiy 商店下载动画模型 2.导入项目 模型拖入到场景中 3.创建动画器控制器 4.动画控制器挂载到plarer上 5.把动画idle和pickup拖入到动画器 6.右键动画创建过渡效果(Make Transition) 6.设置参数用条件控制 7.当选中参数时启动过渡 运行效果 119 (二)用脚本控制动画…

Linux 系统下 如何部署本地 deepseek R1模型

硬件&#xff1a;RTX3090 24G 系统&#xff1a;ubuntu 1804 1. 下载ollama curl -fsSL https://ollama.com/install.sh | sh 2.下载deepseek R1 模型数据 百度网盘下载链接 可以全部都下载&#xff0c;也可以选择性下载&#xff0c;主要看硬件平台 7B的模型大概需要5.5G…

《网络编程卷2:进程间通信》第八章:共享内存深度解析与多进程高性能通信实践

《网络编程卷2&#xff1a;进程间通信》第八章&#xff1a;共享内存深度解析与多进程高性能通信实践 引言 共享内存&#xff08;Shared Memory&#xff09; 是进程间通信&#xff08;IPC&#xff09;中性能最高的机制&#xff0c;允许多个进程直接读写同一块物理内存区域&…

动态DNS神器nip.io使用指南:快速实现域名与IP的动态映射--告别配置本地hosts

动态DNS神器nip.io使用指南&#xff1a;快速实现域名与IP的动态映射--告别配置本地hosts 一、项目简介二、快速入门三、进阶配置四、典型应用场景 本文基于开源项目 v1.2.1版本撰写&#xff0c;适用于开发测试、CI/CD等场景 一、项目简介 nip.io 是由Exentrique Solutions开发…