首页 > 其他分享 >【Leetcode 每日一题】3066. 超过阈值的最少操作数 II

【Leetcode 每日一题】3066. 超过阈值的最少操作数 II

时间:2025-01-15 10:00:47浏览次数:3  
标签:cur nums int long II 3066 heap Leetcode size

问题背景

给你一个下标从 0 0 0 开始的整数数组 n u m s nums nums 和一个整数 k k k。
一次操作中,你将执行:

  1. 选择 n u m s nums nums 中最小的两个整数 x x x 和 y y y。
  2. 将 x x x 和 y y y 从 n u m s nums nums 中删除。
  3. 将 m i n ( x , y ) × 2 + m a x ( x , y ) min(x, y) \times 2 + max(x, y) min(x,y)×2+max(x,y) 添加到数组中的任意位置。

注意,只有当 n u m s nums nums 至少包含两个元素时,你才可以执行以上操作。
你需要使数组中的所有元素都大于或等于 k k k,请你返回需要的 最少 操作次数。

数据约束

  • 2 ≤ n u m s . l e n g t h ≤ 2 × 1 0 5 2 \le nums.length \le 2 \times 10 ^ 5 2≤nums.length≤2×105
  • 1 ≤ n u m s [ i ] ≤ 1 0 9 1 \le nums[i] \le 10 ^ 9 1≤nums[i]≤109
  • 1 ≤ k ≤ 1 0 9 1 \le k \le 10 ^ 9 1≤k≤109
  • 输入保证答案一定存在,也就是说一定存在一个操作序列使数组中所有元素都大于等于 k k k。

解题过程

始终要维护数组中的最小值,用堆很好处理。
用数组实现的手写堆,在平台上的表现比直接调用 API 会好不少。这里用到了之前说实现 堆排序 的过程中可以逃课的向上调整。还是没躲过,索性就记一下。

具体实现

调用优先队列 API

class Solution {
    public int minOperations(int[] nums, int k) {
        Queue<Long> heap = new PriorityQueue<>();
        for(int num : nums) {
            heap.offer((long) num);
        }
        int res = 0;
        while(heap.peek() < k) {
            long min1 = heap.poll();
            long min2 = heap.poll();
            heap.offer(2 * min1 + min2);
            res++;
        }
        return res;
    }
}

自己实现堆

class Solution {
    public int minOperations(int[] nums, int k) {
        int n = nums.length;
        long[] heap = new long[n];
        int size = 0;
        for(int num : nums) {
            heap[size++] = num;
        }
        buildHeap(heap, size);
        int res = 0;
        // 每次循环从最小堆的堆顶取出两个最小值,加入新元素并维护堆结构
        while(heap[0] < k) {
            long min1 = heap[0];
            swap(heap, 0, --size);
            downAdjust(heap, 0, size);
            long min2 = heap[0];
            swap(heap, 0, --size);
            downAdjust(heap, 0, size);
            heap[size++] = 2 * min1 + min2;
            upAdjust(heap, size - 1);
            res++;
        }
        return res;
    }

    // 交换数组中的两个元素
    private void swap(long[] heap, int i, int j) {
        long temp = heap[i];
        heap[i] = heap[j];
        heap[j] = temp;
    }

    // 从当前位置向上调整
    private void upAdjust(long[] heap, int cur) {
        while(heap[cur] < heap[(cur - 1) / 2]) {
            swap(heap, cur, (cur - 1) / 2);
            cur = (cur - 1) / 2;
        }
    }

    // 从当前位置向下调整
    private void downAdjust(long[] heap, int cur, int size) {
        int child = 2 * cur + 1;
        // 注意这里是子节点不超过数组范围
        while(child < size) {
            int target = child + 1 < size && heap[child + 1] < heap[child] ? child + 1 : child;
            target = heap[target] < heap[cur] ? target : cur;
            if(target == cur) {
                break;
            }
            swap(heap, cur, target);
            cur = target;
            child = 2 * cur + 1;
        }
    }

    // 自底向顶建堆
    private void buildHeap(long[] heap, int size) {
        for(int i = size; i >= 0; i--) {
            downAdjust(heap, i, size);
        }
    }
}

标签:cur,nums,int,long,II,3066,heap,Leetcode,size
From: https://blog.csdn.net/2401_88859777/article/details/145153975

相关文章

  • 【Leetcode 热题 100】295. 数据流的中位数
    问题背景中位数是有序整数列表中的中间值。如果列表的大小是偶数,则没有中间值,中位数是两个中间值的平均值。例如arr=......
  • js 调用 IIS部署的 WebAPI 相关配置
    1.跨域问题处理需要在web.config添加节点<system.webServer><httpProtocol><customHeaders><addname="Access-Control-Allow-Origin"value="*"/><addname="Access-Control-Allow-Headers"......
  • 【LeetCode】回文链表
    【LeetCode】回文链表......
  • ryujin 1.2.78下载(龙神模拟器),配置19.0的key和对应固件,解决amiibo API错误(需要翻墙vpn)
    1.下载不废话Release1.2.78·Ryubing/Ryujinx·GitHub,找对应的版本下载下载后解压得到publish文件夹,打开里面的Ryujinx.exe,会报错,别管先挂着,接着看步骤22.配置switch的key和固件推荐(不用vpn):下面步骤2.1和2.2 key和固件的下载要使用vpn,你可以直接用夸克打开下面......
  • LeetCode:23.合并K个排序链表
    LeetCode:23.合并K个排序链表解题思路新链表的下一个节点一定是k个链表头中的最小节点。考虑选择使用最小堆。解题步骤构建一个最小堆,并依次把链表头插入堆中。弹出堆顶接到输出链表,并将堆顶所在链表的新链表头插入堆中。等堆元素全部弹出,合并工作就完成了。classMinHeap{......
  • LeetCode:347.前K个高频元素
    LeetCode:347.前K个高频元素vartopKFrequent=function(nums,k){letmap=newMap();letarr=[...newSet(nums)]nums.forEach(item=>{if(map.has(item)){map.set(item,map.get(item)+1)}else{map.set(item,1)......
  • LeetCode:40.组合总和II
    跟着carl学算法,本系列博客仅做个人记录,建议大家都去看carl本人的博客,写的真的很好的!代码随想录LeetCode:40.组合总和II给定一个候选人编号的集合candidates和一个目标数target,找出candidates中所有可以使数字和为target的组合。candidates中的每个数字在每......
  • LeetCode - #183 Swift 实现查询未下订单的客户
    网罗开发(小红书、快手、视频号同名)  大家好,我是展菲,目前在上市企业从事人工智能项目研发管理工作,平时热衷于分享各种编程领域的软硬技能知识以及前沿技术,包括iOS、前端、HarmonyOS、Java、Python等方向。在移动端开发、鸿蒙开发、物联网、嵌入式、云原生、开源......
  • 【LeetCode 刷题】二分搜索
    此博客作为《代码随想录》的学习笔记,主要内容为二分搜索法及相关题目解析。文章目录704.二分查找35.搜索插入位置34.在排序数组中查找元素的第一个和最后一个位置69.x的平方根367.有效的完全平方数以下所有二分法算法均基于左闭右闭区间704.二分查找LeetCode......
  • 如何在不重启IIS的情况下回收IIS程序池?
    问题描述:在服务器管理中,有时需要回收IIS程序池以释放资源或解决某些问题,但又不想重启整个IIS服务。请问如何在不重启IIS的情况下回收IIS程序池?具体操作步骤是什么?如果通过远程桌面连接到服务器进行操作,需要注意哪些事项?答案:您好,回收IIS程序池而不重启IIS是一个常见的操作,尤其是......