力扣215.数组中的第K个最大元素
Posted 一个拿着底层薪资操着架构师的心的码农
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了力扣215.数组中的第K个最大元素相关的知识,希望对你有一定的参考价值。
215. 数组中的第K个最大元素
在未排序的数组中找到第 k 个最大的元素。请注意,你需要找的是数组排序后的第 k 个最大的元素,而不是第 k 个不同的元素。
示例 1:
输入: [3,2,1,5,6,4] 和 k = 2 输出: 5
示例 2:
输入: [3,2,3,1,2,4,5,5,6] 和 k = 4 输出: 4
说明:
你可以假设 k 总是有效的,且 1 ≤ k ≤ 数组的长度。
思路一:排序后取值
复杂度分析:
时间复杂度:排序时间为O(nlogn),所以时间为O(nlogn)
空间复杂度:O(1)
思路二:利用堆
维持一个大小为K的最小堆,堆顶的元素始终是当前所有元素中第K大的元素
1 class Solution { 2 public int findKthLargest(int[] nums, int k) { 3 PriorityQueue<Integer> heap = new PriorityQueue<>(); // 最小堆 4 for(int i : nums){ 5 heap.offer(i); 6 if(heap.size() > k){ 7 heap.poll(); // 维持堆的大小为k 8 } 9 } 10 return heap.poll(); 11 } 12 }
力扣测试时间为:6ms, 空间为40.2MB
复杂度分析:
时间复杂度:一个维持堆大小为k的过程,所以时间复杂度为O(Nlogk)
空间复杂度:O(k),也就是堆的大小
思路三:
借助快排的过程
1 class Solution { 2 public int findKthLargest(int[] nums, int k) { 3 // 借助快排的过程 4 return quickSort(nums, 0, nums.length - 1, nums.length - k); 5 } 6 7 public int partition(int[] nums, int left, int right){ 8 // 选取第一个元素为主元 9 int pivot = nums[left]; 10 11 while(left < right){ 12 while(left < right && nums[right] >= pivot){ 13 right--; 14 } 15 nums[left] = nums[right]; 16 17 while(left < right && nums[left] <= pivot){ 18 left++; 19 } 20 nums[right] = nums[left]; 21 } 22 nums[left] = pivot; 23 return left; 24 } 25 26 public int quickSort(int[] nums, int left, int right, int k){ 27 // 如果经过一轮快排分区后主元位置刚好是k,那么可以直接退出了 28 int mid = partition(nums, left, right); 29 if(mid == k){ 30 return nums[k]; 31 }else if(mid > k){ 32 return quickSort(nums, left, mid - 1, k); 33 }else{ 34 return quickSort(nums, mid + 1, right, k); 35 } 36 } 37 }
力扣测试时间为9ms, 空间为40.6MB
复杂度分析:
时间复杂度:每次将数组分成两段,只会选择其中一段进行partition操作,所以时间复杂度为O(N+N/2 + N/4 + 1) =,所以时间复杂度为O(N)
空间复杂度为:O(1)
思路参考:
以上是关于力扣215.数组中的第K个最大元素的主要内容,如果未能解决你的问题,请参考以下文章
LeetCode 215. 数组中的第K个最大元素 | Python