• 算法学习笔记-LeetCode215-数组中的第K个最大元素


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

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

    你必须设计并实现时间复杂度为 O(n) 的算法解决此问题。
    分析:
    通过该题学习堆排序的写法,当然堆排复杂度是nlog(n)。
    堆是一种完全二叉树,该树中所有节点都满足节点大小大于左右任意一个子节点的大小。从定义不难看出,根节点是树中最大的。
    堆排序的原理是,建立一个大根堆,然后每次取出堆顶的元素,也就是当前最大的元素放到队列中,取出堆顶元素后,再从从堆底部取一个元素放置到堆顶,从堆顶向下迭代到新元素根据其大小应该在的位置(目的是使新的树依然满足大顶堆的定义)。每次取出当前最大值,自然就能完成排序,算法重点在于一个函数maxHeapify。
    这个函数的用处是,对于堆,也就是树中的一个节点a,每次比较这个节点a和其左右子节点(b,c)的大小,把最大的节点放到a的位置,如果发生了这种交换,比如a被换到了b的位置,就要从b的位置再次向下交换。因为没有发生改变的c 和其子树依然满足大顶堆的定义,但是b因为变小了,可能不会再满足大顶堆的定义,也就是可能不满足比它的任意子节点大,此时需要再递归调用函数maxHeapify处理b节点,直到处理到堆底。
    其中,二叉树是用数组存储的,规定下标为i的数组元素对应的节点,其左孩子节点放在数组中下标为2i+1的位置,右孩子放置在数组中下标为2i+2的位置。
    堆排序的顺序如下:
    1,建堆,具体方法是从堆底部(倒数第二层)开始,调用maxHeapify方法,即比较节点和其子节点大小,子节点大则把父节点向下放。这样底部的两层节点满足大顶堆的要求,然后用maxHeapify处理上一层的节点,直到顶部。
    2,此时堆中的元素全部存储到数组中,堆顶存储在下标0的位置,把下标0和下标len-1交换,即把堆顶的最大元素取出堆,作为当前最大元素,放到数组末尾,此时堆大小减一,即堆元素存储在0~len-2的位置。然后从堆顶调用maxHeapify函数向下处理元素,使得该堆再次满足大顶堆的定义,再从堆顶部取出当前堆的最大值,放到len-2的位置,原来len-2的元素放到0上作为堆顶,堆元素此时是0到len-3的元素,重复上述过程最后数组中元素就是排序好的元素。

  • 相关阅读:
    [每日两题系列]刷算法题咯~~
    用户终身价值利用xgboost进行LTV预测
    Spring学习笔记9 SpringIOC注解式开发
    字符函数和字符串函数(详解大全)
    SpringCloud微服务(八)——OpenFeign服务调用
    ​金属外壳笔记本电脑会触电吗?
    Locust如何实现逐步负载?
    yolo自动化项目实例解析(一)日志格式输出、并发异步多线程、websocket、循环截图、yolo推理、3d寻路
    若依分离版——配置多数据源(mysql和oracle),实现一个方法操作多个数据源
    什么是项目管理?一文了解项目管理的概念、历史、内容和方法
  • 原文地址:https://blog.csdn.net/qq_42801735/article/details/127434629