[Go版]算法通关村第十四关白银——堆高效解决的经典问题(在数组找第K大的元素、堆排序、合并K个排序链表)

news2024/9/29 13:15:05

目录

题目:在数组中找第K大的元素

题目链接:LeetCode-215. 数组中的第K个最大元素
在这里插入图片描述

解法1:维护长度为k的最小堆,遍历n-k个元素,逐一和堆顶值对比后,和堆顶交换,最后返回堆顶

复杂度:时间复杂度 O ( k + ( n − k ) l o g k ) O(k+(n-k)logk) O(k+(nk)logk)、空间复杂度 O ( 1 ) O(1) O(1)

Go代码

func findKthLargest(nums []int, k int) int {
    length := len(nums)
    if k > length {
        return -1
    }
    makeMinHeap(nums, k)
    for i:=k;i<length;i++ {
        if nums[i] > nums[0] {
            nums[0], nums[i] = nums[i], nums[0]
            minHeap(nums, 0, k)
        }
    }
    return nums[0]
}

func makeMinHeap(arr []int, length int) {
    // 从最后一个非叶子节点开始
    for i:=(length/2-1); i>=0; i-- {
        minHeap(arr, i, length)
    }
}

// 最小堆化
func minHeap(arr []int, i int, length int) {
    left, right := 2*i+1, 2*i+2
    min := i
    if left < length && arr[left] < arr[min] {
        min = left
    }
    if right < length && arr[right] < arr[min] {
        min = right
    }
    if min != i {
        arr[i], arr[min] = arr[min], arr[i]
        minHeap(arr, min, length)
    }
}

解法2:构建长度为n的最大堆,遍历k次,每次删除堆顶,且堆长度-1,最后返回堆顶(k较小时此法更优)

复杂度:时间复杂度 O ( n + k l o g n ) O(n+klogn) O(n+klogn)、空间复杂度 O ( 1 ) O(1) O(1)

Go代码

func findKthLargest(nums []int, k int) int {
    length := len(nums)
    if k > length {
        return -1
    }
    // 将nums构建为一个最大堆
    makeMaxHeap(nums, length)
    for i:=1; i<k; i++ {
        nums[0], nums[length-i] = nums[length-i], nums[0]
        maxHeap(nums, 0, length-i)
    }
    return nums[0]
}

// 最大堆
func makeMaxHeap(arr []int, length int) {
    // 第一个非叶子节点
    for i:=(length/2-1); i>=0; i-- {
        maxHeap(arr, i, length)
    }
}
// 最大堆化
func maxHeap(arr []int, i int, length int) {
    l, r, max := 2*i+1, 2*i+2, i
    if l<length && arr[l] > arr[max] {
        max = l
    }
    if r<length && arr[r] > arr[max] {
        max = r
    }
    if max != i {
        arr[max], arr[i] = arr[i], arr[max]
        maxHeap(arr, max, length)
    }
}

题目:堆排序

题目链接:LeetCode-912. 排序数组
在这里插入图片描述

思路分析:构建长度为n的最大堆,依次删除堆顶并逆序放到数组尾部,且堆长度-1,n-1次后数组则为升序

复杂度:时间复杂度 O ( n l o g ( n ) ) O(nlog(n)) O(nlog(n))、空间复杂度 O ( 1 ) O(1) O(1)

Go代码

func sortArray(nums []int) []int {
    length := len(nums)
    if length == 1 {
        return nums
    }
    makeMaxHeap(nums, length)
    for i:=length-1; i>0; i-- {
        nums[0], nums[i] = nums[i], nums[0]
        maxHeap(nums, 0, i)
    }
    return nums
}
// 构建最大堆
func makeMaxHeap(nums []int, length int) {
    // 第一个非叶子结点
    for i:=length/2-1; i>=0; i-- {
        maxHeap(nums, i, length)
    }
}
// 最大堆化
func maxHeap(nums []int, i int, length int) {
    l, r, max := 2*i+1, 2*i+2, i
    if l<length && nums[l] > nums[max] {
        max = l
    }
    if r<length && nums[r] > nums[max] {
        max = r
    }
    if max != i {
        nums[max], nums[i] = nums[i], nums[max]
        maxHeap(nums, max, length)
    }
}

题目:合并K个排序链表

题目链接:LeetCode-23. 合并 K 个升序链表
在这里插入图片描述

思路分析:维护长度为k的最小堆,依次删除堆顶接到返回链表上(纵向拼接),注意取值时判断空链表

复杂度:时间复杂度 O ( k + n l o g k ) O(k+nlogk) O(k+nlogk)、空间复杂度 O ( 1 ) O(1) O(1)

Go代码

/**
 * Definition for singly-linked list.
 * type ListNode struct {
 *     Val int
 *     Next *ListNode
 * }
 */
func mergeKLists(lists []*ListNode) *ListNode {
    length := len(lists)
    if length == 1 {
        return lists[0]
    }
    // 去除空数组
    for i:=0; i<length; i++ {
        if lists[i] == nil {
            lists[i], lists[length-1] = lists[length-1], lists[i]
            length--
            i--
        }
    }
    newList := &ListNode{}
    tmp := newList
    // 最小化
    makeMinHeap(lists, length)
    for length > 0 && lists[0] != nil {
        // 取出当前最小
        tmp.Next = &ListNode{Val:lists[0].Val}
        tmp = tmp.Next
        lists[0] = lists[0].Next
        if lists[0] == nil {
            lists[0], lists[length-1] = lists[length-1], lists[0]
            length--
        }
        if length > 0 && lists[0] != nil {
            minHeap(lists, 0, length)
        }
    }
    return newList.Next
}

func makeMinHeap(arr []*ListNode, length int) {
    for i:=length/2-1; i>=0; i-- {
        minHeap(arr, i, length)
    }
}

func minHeap(arr []*ListNode, i, length int) {
    left, right, min := 2*i+1, 2*i+2, i
    if left<length && arr[left].Val < arr[min].Val {
        min = left
    }
    if right<length && arr[right].Val < arr[min].Val {
        min = right
    }
    if min != i {
        arr[min], arr[i] = arr[i], arr[min]
        minHeap(arr, min, length)
    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/933440.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

大数据治理运营整体解决方案[39页PPT]

导读&#xff1a;原文《大数据治理运营整体解决方案[39页PPT]》&#xff08;获取来源见文尾&#xff09;&#xff0c;本文精选其中精华及架构部分&#xff0c;逻辑清晰、内容完整&#xff0c;为快速形成售前方案提供参考。 数据治理总体方案 数据治理平台解决方案 数据治理运…

nginx生成自定义证书

1、创建key文件夹 [rootlocalhost centos]# mkdir key 进入key文件夹 [rootlocalhost centos]# cd key/ 2、生成私钥文件 [rootlocalhost key]# openssl genrsa -des3 -out ssl.key 4096 输入这个key文件的密码。不推荐输入&#xff0c;因为以后要给nginx使用。每次reload ngin…

yolov8热力图可视化

安装pytorch_grad_cam pip install grad-cam自动化生成不同层的bash脚本 # 循环10次&#xff0c;将i的值从0到9 for i in $(seq 0 13) doecho "Running iteration $i";python yolov8_heatmap.py $i; done热力图生成python代码 import warnings warnings.filterwarn…

如何延长周末体验感

美好的周末永远都是从周五开始 为了享受周末的美好时光一定要在周五下班前把工作中应该处理的事情处理好&#xff0c;避免突发事件影响后续的计划。 此外过周五晚上开始做让自己感到开心的事情&#xff0c;以此让自己感觉到周末已经开始了。包括单不限于 享受美食 周五晚上是一…

【业务功能篇84】微服务SpringCloud-ElasticSearch-Kibanan-电商实例应用

一、商品上架功能 ElasticSearch实现商城系统中全文检索的流程。 1.商品ES模型 商品的映射关系 PUT product {"mappings": {"properties": {"skuId": {"type": "long"},"spuId": {"type": "ke…

mall:redis项目源码解析

文章目录 一、mall开源项目1.1 来源1.2 项目转移1.3 项目克隆 二、Redis 非关系型数据库2.1 Redis简介2.2 分布式后端项目的使用流程2.3 分布式后端项目的使用场景2.4 常见的缓存问题 三、源码解析3.1 集成与配置3.1.1 导入依赖3.1.2 添加配置3.1.3 全局跨域配置 3.2 Redis测试…

DataFrame.set_index()方法--Pandas

1.函数功能 为DataFrame重新设置索引&#xff08;行标签&#xff09; 2. 函数语法 DataFrame.set_index(keys, *, dropTrue, appendFalse, inplaceFalse, verify_integrityFalse)3. 函数参数 参数含义keys作为行标签的列名&#xff0c;可以DataFrame中的是单个列或者多列组…

【实例分割】(一)Mask R-CNN详细介绍带python代码

目录 1.&#x1f340;&#x1f340;实例分割定义 2.&#x1f340;&#x1f340;Mask R-CNN 3.&#x1f340;&#x1f340;经典的实例分割算法 4.&#x1f340;&#x1f340;Mask R-CNN python代码 整理不易&#xff0c;欢迎一键三连&#xff01;&#xff01;&#xff01;…

【FreeRTOS】【应用篇】任务管理相关函数

文章目录 前言一、函数解析1. 任务挂起 vTaskSuspend()① 使用场景② 设计思路③ 代码 2. 任务恢复 vTaskResume()① 作用② 设计思路③ 代码 3. 挂起任务调度器 vTaskSuspendAll()① 作用② 代码 4. 恢复任务调度器 xTaskResumeAll()① 设计思路② 代码 5. 任务删除函数 vTask…

牡丹宣言:七种皮肤类型|教你如何区分和保姆级护肤大法

经常听到有人说&#xff0c;我的皮肤T区油&#xff0c;脸颊干&#xff0c;应该是混合型皮肤吧 正常的皮肤根据皮脂腺分泌油脂量的多少可分为&#xff1a;中性&#xff0c;干性&#xff0c;油性&#xff0c;混合性。 接下来小编就帮大家细化整理了七种不同的皮肤类型&#xff0c…

Nginx详解 第一部分:编译安装Nginx+Nginx模块

Part 1 一 、HTTP 和 Nginx1.1 套接字Socket1.2 URL1.2.1 定义1.2.1 URL和URN的区别1.2.3 URL组成 1.3 请求访问完整过程详解 二、I/O模型 处理高并发的时候用2.1 I/O模型简介2.2 多路复用I/O型2.3 异步I/O模型2.4 事件模型 select poll epoll 三、NGINX概述3.1 简介3.2 NGINX和…

【Java并发】聊聊对象内存布局和syn锁升级过程

对象存储解析&#xff1a;一个空Object对象到底占据多少内存&#xff1f; 对象内存布局 Mark Word占用8字节&#xff0c;类型指针占用8个字节&#xff0c;对象头占用16个字节。 好了&#xff0c;我们来看一下一个Object对占用多少空间&#xff0c; 因为java默认是开启压缩…

帆软只是一个BI厂商?答案是“No”!

大数据产业创新服务媒体 ——聚焦数据 改变商业 2023年&#xff0c;8月17-19日&#xff0c;帆软智数大会落子花城广州&#xff0c;邀请了1200海内外CIO和数字化专家&#xff0c;共同探讨数字化转型新机遇。 值得关注的是&#xff0c;这也是帆软首次以BI和零代码双赛道第一的身…

django开发流程

设计model django采用ORM映射&#xff0c;可以在代码中描述数据库的布局 只需要导入from django.db import models 并使类继承models.Model&#xff0c;models中的一个类对应数据库中的一个表&#xff0c;类的变量对应表字段。 创建数据库 $ python manage.py makemigration…

Ubuntu【系统环境下】【编译安装OpenCV】【C++调用系统opencv库】

Ubuntu【系统环境下】【编译安装OpenCV】【C调用系统opencv库】 前言&#xff1a; 本人需要用C写代码&#xff0c;调用OpenCV库&#xff0c;且要求OpenCV版本号大于4.1.0 由于使用的是18.04的版本&#xff0c;所以apt安装OpenCV的版本始终是3.2.0&#xff0c;非常拉胯&#…

python爬虫的js逆向入门到进阶教程文章分享汇总~持续更新

目录 一、内容介绍二 、专栏内容-持续更新1、JS逆向入门2、Js逆向进阶3、爬虫基础知识4、工具与安装5、漫星内容分享 三、星球使用四、b站up主视频推荐 一、内容介绍 二 、专栏内容-持续更新 1、JS逆向入门 2023-08-25》11.常见加密>xx音乐RSA加密 https://articles.zsxq.c…

电视乱收费致200元电视也无人买,广电总局出手了,用户拍手欢迎

各个互联网企业盯着电视用户&#xff0c;将用户当韭菜&#xff0c;收费太狠&#xff0c;导致国内市场的电视销量暴跌&#xff0c;消费者怨声载道&#xff0c;日前国家广播电视台联合其他部门开展专项整治&#xff0c;狠杀这类乱收费的乱象&#xff0c;或许将有望挽回用户。 近几…

报错处理:MySQL数据库连接超时

具体报错&#xff1a; ERROR 2002 (HY000): Cant connect to local MySQL server through socket /var/run/mysqld/mysqld.sock (2) 报错环境&#xff1a;该报错一般发生在Linux服务器上运行MySQL数据库时&#xff0c;尝试连接MySQL时出现连接超时的情况。 排错思路&#xff1a…

VIOOVI分享:什么是动作分析?动作分析的方法有哪些?

动作分析是由吉尔布雷斯夫妇始创的&#xff0c;是根据操作者实施的动作顺序观察动作&#xff0c;用特定的标记记录以手和眼睛为中心的人体各部位的动作内容&#xff0c;掌握实际情况&#xff0c;并将上述记录制成图表的一套分析方法&#xff0c;在此基础上判断动作质量&#xf…

Docker容器学习:Dockerfile制作Web应用系统nginx镜像

目录 编写Dockerfile 1.文件内容需求&#xff1a; 2.编写Dockerfile&#xff1a; 3.开始构建镜像 4.现在我们运行一个容器&#xff0c;查看我们的网页是否可访问 推送镜像到私有仓库 1.把要上传的镜像打上合适的标签 2.登录harbor仓库 3.上传镜像 编写Dockerfile 1.文…