leetcode 215. Kth Largest Element in an Array | 215. 数组中的第K个最大元素(Java)
题目
https://leetcode.com/problems/kth-largest-element-in-an-array/
题解
本题需要建立大顶堆。关于堆的数据结构,需要知道:
堆
什么是堆?
堆 是一棵 完全二叉树:即使它不是满二叉树,也是正在从左往右变满的过程中。
1)堆结构就是用数组实现的完全二叉树结构
2)完全二叉树中,如果每棵子树的 最大值都在顶部,是 大根堆
3)完全二叉树中,如果每棵子树的 最小值都在顶部,是 小根堆
4)堆结构的 heapInsert 与 heapify 操作
5)堆结构的增大和减少
6)优先级队列结构,就是堆结构
7)特点:由 N 个数 组成的堆,高度是 log(n)
如何用数组存放堆?
如果从 0 位置开始:
i 层,则
- 左孩子:2 * i + 1
- 右孩子:2 * i + 2
- 父节点:(i - 1) / 2
如果从 1 位置开始:
正是由于可以使用 位运算 来代替 算数运算,效率更高,所以有时候让下标从 1 开始。
- 左孩子:2 * i (i << 1)
- 右孩子:2 * i + 1 (i << 1 | 1)
- 父节点:i / 2 (i >> 1)
如何将数组转化成大根堆?—— heapInsert 操作
每在 i 位置加入一个新的节点,都与它的 (i - 1) / 2 位置的父节点比较,如果比父节点大,则交换(并while比较父节点与父父节点)
private void heapInsert(int[] arr, int index) {while (arr[index] > arr[(index - 1) / 2]) {swap(arr, index, (index - 1) / 2);index = (index - 1) / 2;}
}
private void swap(int[] arr, int i, int j) {int tmp = arr[i];arr[i] = arr[j];arr[j] = tmp;
}
如何返回并删除大根堆的最大值,剩余数字依然保持大根堆?—— heapify 操作
- 将顶部元素取出
- 将大根堆的最后位置上的元素覆盖到顶部
- while 循环
- 如果左右孩子中较大的数比当前节点更大,则交换当前节点和较大的孩子节点
- 如果左孩子下标越界,或左右孩子都不比当前节点大,就停止
// 返回最大值,并在大根堆中把最大值删掉,剩下的数依然保持大根堆形态
public int pop() {int ans = heap[0];swap(heap, 0, --heapSize);heapify(heap, 0, heapSize);return ans;
}
// 从index位置开始,不断的下沉,直到我的孩子都不再比我大,或者我已经没孩子了,就停止
private void heapify(int[] arr, int index, int heapSize) {int left = index * 2 + 1;while (left < heapSize) {// largest存储左右孩子 较大者 的下标int largest = left + 1 < heapSize && arr[left + 1] > arr[left] ? left + 1 : left;// largest存储两个孩子与父节点 较大者 的下标largest = arr[largest] > arr[index] ? largest : index;if (largest == index) { // 不需要交换的情况break;}swap(arr, largest, index);index = largest;left = index * 2 + 1;}
}
堆排序
- 先让整个数组都变成大根堆结构,建立堆的过程:
- 从上到下的方法,时间复杂度为O(N*logN)
- 从下到上的方法,时间复杂度为O(N)
- 把堆的最大值和堆末尾的值交换,然后减少堆的大小之后,再去调整堆,一直周而复始,时间复杂度为O(N*logN)
- 堆的大小减小成0之后,排序完成!
public static void heapSort(int[] arr) {if (arr == null || arr.length < 2) {return;}// 方法1:对数组进行堆排序 O(N*logN)for (int i = 0; i < arr.length; i++) { // O(N)heapInsert(arr, i); // O(logN)}// 方法2:仅将数组转化成大顶堆 O(n) for (int i = arr.length - 1; i >= 0; i--) {heapify(arr, i, arr.length);}
}
本题代码
class Solution {int[] nums;int heapSize;public int findKthLargest(int[] nums, int k) {this.nums = nums;this.heapSize = nums.length;// 先让整个数组变成大根堆结构// 方法1:从上至下 对数组进行堆排序 O(N*logN)
// for (int i = 0; i < nums.length; i++) // O(N)
// heapInsert(nums, i); // O(logN)// 方法2:从下至上 仅将数组转化成大顶堆 O(N)for (int i = nums.length - 1; i >= 0; i--)heapify(nums, i, nums.length);int result = -1;for (int i = 0; i < k; i++)result = pop();return result;}public int pop() {int max = nums[0];swap(nums, 0, --heapSize);heapify(nums, 0, heapSize);return max;}// 方法1 从上至下调整堆:每在i位置加入一个新的节点,都与它的(i-1)/2位置的父节点比较,如果比父节点大,则交换(并while比较父节点与父父节点)private void heapInsert(int[] arr, int index) {while (arr[index] > arr[(index - 1) / 2]) {swap(arr, index, (index - 1) / 2);index = (index - 1) / 2;}}// 方法2 从下至上调整堆:从index位置开始,不断的下沉,直到我的孩子都不再比我大,或者我已经没孩子了,就停止public void heapify(int[] arr, int i, int heapSize) {int left = i * 2 + 1;while (left < heapSize) {int largest = left + 1 < heapSize && nums[left + 1] > nums[left] ? left + 1 : left; // 左右孩子较大者的下标largest = nums[largest] > nums[i] ? largest : i; // 两个孩子与父节点较大者的下标if (largest == i) break; // 不需要交换的情况swap(arr, largest, i);i = largest; // 更新i使其下沉left = 2 * i + 1;}}private void swap(int[] arr, int i, int j) {int tmp = arr[i];arr[i] = arr[j];arr[j] = tmp;}
}
leetcode 215. Kth Largest Element in an Array | 215. 数组中的第K个最大元素(Java)相关推荐
- 剑指offer 最小的k个数 leetcode 215. Kth Largest Element in an Array
注意multiset的一个bug: multiset带一个参数的erase函数原型有两种.一是传递一个元素值,如上面例子代码中,这时候删除的是集合中所有值等于输入值的元素,并且返回删除的元素个数:另外 ...
- 网易2016 实习研发工程师 [编程题]寻找第K大 and leetcode 215. Kth Largest Element in an Array...
传送门 有一个整数数组,请你根据快速排序的思路,找出数组中第K大的数. 给定一个整数数组a,同时给定它的大小n和要找的K(K在1到n之间),请返回第K大的数,保证答案存在. 测试样例: [1,3,5, ...
- [swift] LeetCode 215. Kth Largest Element in an Array
Find the kth largest element in an unsorted array. Note that it is the kth largest element in the so ...
- [leedcode 215] Kth Largest Element in an Array
Find the kth largest element in an unsorted array. Note that it is the kth largest element in the so ...
- 215. Kth Largest Element in an Array 数组中的第K个最大元素
Title 在未排序的数组中找到第 k 个最大的元素.请注意,你需要找的是数组排序后的第 k 个最大的元素,而不是第 k 个不同的元素. 示例 1: 输入: [3,2,1,5,6,4] 和 k = 2 ...
- LeetCode 215 Kth Largest Element in an Array
思路: 跟找第kth小的数相反,数组逆向排序.从前找第k - 1个数. 1 public class Solution { 2 public int findKthLargest(int[] arra ...
- leetcode之Kth Largest Element in an Array
这题是求出来排序好的数的第k个大的数.用了.sort()之后就非常简单了.不用自己排序的表示真是简单啊.然而真讲排序我还基本不会...代码如下: class Solution(object):def ...
- 力扣215:数组中的第K个最大元素 (leetcode 215:Kth Largest Element In An Array)
题目链接:https://leetcode.cn/problems/kth-largest-element-in-an-array 目录: 一.题目描述 1.中文 2.英文 二.解决方法 1.直接排序 ...
- LeetCode 215. Kth Largest Element in an Array--数字第K大的元素--最大堆或优先队列--C++,Python解法
题目地址:Kth Largest Element in an Array - LeetCode Find the kth largest element in an unsorted array. N ...
最新文章
- 60秒计时器的仿真电路_物联网应用基于Arm微控制器的低功耗定时关机计时器
- PHP怎么做一个加法口诀,神奇的手指速算口诀,100以内的加减法一分钟学会
- mysql pmod项目_内置函数 - 数学函数 - 《Apache Doris 文档(201812)》 - 书栈网 · BookStack...
- python导入xlrd库_python中xlrd库如何实现文件读取?
- 如何进行cad地理配准_【教程】自带高度建筑轮廓如何制作分色图
- DMSP/OLS夜间灯光数据
- SQL Server 各版本密钥
- 哈工大本部2022形式语言与自动机期末试题
- 如何提高服务器网站访问速度,如何有效提升网站打开速度?
- HEVC解码器HM源码阅读(二)解码器中类的介绍
- MTK AF Tuning Preparation项目
- 岁月安好,不存在的!不过是有人替你负重前行
- 靶机渗透练习43-Lord Of The Root
- android开发(43) 动画演示,会跑的小人,从屏幕左侧跑到右侧
- Rhel 7.3 基本操作
- Z-BlogPHP蓝色简约风格网址收录导航网站模板
- Scanpy Umap 3D
- oracle rman备份时间点,Oracle Rman 控制RMAN的备份时间,减少IO消耗
- php 不恒等,Re: 弱问:Latex里不恒等号(三横一撇) - 精华区 - 数学科学学院(SMS)版 - 北大未名BBS...
- 2022年最新版的运维面试题【从基础到精通】
热门文章
- HDU - 1796 How many integers can you find(容斥原理)
- POJ - 1201 Intervals(差分约束+最短路)
- uva1624knots
- php tp框架调用方法,thinkPHP框架使用方法
- L1-036. A乘以B
- BZOJ2806(后缀自动机+DP)
- [51nod1847][算法马拉松23(飞越愚人节)F]奇怪的数学题
- 《openssl编程》之配置文件
- 基于WSAAsyncSelect模型实现的聊天室图形客户端
- 精美技术图赏-技术精华|二期