博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
[LeetCode] 215. Kth Largest Element in an Array 数组中第k大的元素
阅读量:5250 次
发布时间:2019-06-14

本文共 6348 字,大约阅读时间需要 21 分钟。

Find the kth largest element in an unsorted array. Note that it is the kth largest element in the sorted order, not the kth distinct element.

Example 1:

Input: [3,2,1,5,6,4] and k = 2Output: 5

Example 2:

Input: [3,2,3,1,2,4,5,5,6] and k = 4Output: 4

Note: 

You may assume k is always valid, 1 ≤ k ≤ array's length.

找出一个非排序数组中第k大的元素。

解法1:排序法。使用常规排序方法后找到数组中对应下标的值。

解法2:将数组内容存入一升序优先队列中,进行k-1次pop操作,那么队尾的元素就是第k大的数字。

解法3:最大堆MaxHeap。使用数组内容构建一个最大堆,通过每次pop出堆顶后继续维护堆的结构,直到满足一定的次数(最大堆k-1次,最小堆size-k次),堆顶的元素就是第k大的数字,实现的效果与优先队列相同。

解法4:Quick Select, 利用快排的partition函数思想,选定一个数组内的值作为pivot,将小于pivot的数字放到pivot右边,大于等于pivot的数字放到pivot左边。接着判断两边数字的数量,如果左边的数量小于k个,说明第k大的数字存在于pivot及pivot右边的区域之内,对右半区执行partition函数;如果右边的数量小于k个,说明第k大的数字在pivot和pivot左边的区域之内,对左半区执行partition函数。直到左半区刚好有k-1个数,那么第k大的数就已经找到了。

Java: Sort, T: O(nlogn) S: O(1)

public class Solution {    public int findKthLargest(int[] nums, int k) {        Arrays.sort(nums);        return nums[nums.length - k];    }}

Java: MaxHeap, T: O(nlogk) S: O(k)

public class Solution {    public int findKthLargest(int[] nums, int k) {        PriorityQueue
p = new PriorityQueue
(); for(int i = 0 ; i < nums.length; i++){ p.add(nums[i]); if(p.size()>k) p.poll(); } return p.poll(); }}

Java: Quick select, T: Avg O(n) Worst O(n^2), S: O(1)

public class Solution {    public int findKthLargest(int[] nums, int k) {        return quickSelect(nums, k - 1, 0, nums.length - 1);    }        private int quickSelect(int[] arr, int k, int left, int right){        int pivot = arr[(left + right) / 2];        int orgL = left, orgR = right;        while(left <= right){            // 从右向左找到第一个小于枢纽值的数            while(arr[left] > pivot){                left ++;            }            // 从左向右找到第一个大于枢纽值的数            while(arr[right] < pivot){                right --;            }            // 将两个数互换            if(left <= right){                swap(arr, left, right);                left ++;                right --;            }        }        // 最后退出的情况应该是右指针在左指针左边一格        // 这时如果右指针还大于等于k,说明kth在左半边        if(orgL < right && k <= right) return quickSelect(arr, k, orgL, right);        // 这时如果左指针还小于等于k,说明kth在右半边        if(left < orgR && k >= left) return quickSelect(arr, k, left, orgR);        return arr[k];        }        private void swap(int[] arr, int idx1, int idx2){        int tmp = arr[idx1] + arr[idx2];        arr[idx1] = tmp - arr[idx1];        arr[idx2] = tmp - arr[idx2];        }} 

Python: Sort

class Solution:    # @param {integer[]} nums    # @param {integer} k    # @return {integer}    def findKthLargest(self, nums, k):        return sorted(nums, reverse=True)[k - 1]

Python: Max Heap

from heapq import *class Solution(object):    def findKthLargest(self, nums, k):        """        :type nums: List[int]        :type k: int        :rtype: int        """        if not nums:            return -1                h = []        for i in xrange(len(nums)):            if len(h) < k:                heappush(h, nums[i])            else:                if h[0] < nums[i]:                    heappop(h)                    heappush(h, nums[i])        return h[0]

Python: Quick select

import randomclass Solution:    def findKthLargest(self, nums, k):        pivot = random.choice(nums)        nums1, nums2 = [], []        for num in nums:            if num > pivot:                nums1.append(num)            elif num < pivot:                nums2.append(num)        if k <= len(nums1):            return self.findKthLargest(nums1, k)        if k > len(nums) - len(nums2):            return self.findKthLargest(nums2, k - (len(nums) - len(nums2)))        return pivot

Python: Quick select

class Solution:    # @param {integer[]} nums    # @param {integer} k    # @return {integer}    def findKthLargest(self, nums, k):        left, right = 0, len(nums) - 1        while left <= right:            pivot_idx = randint(left, right)            new_pivot_idx = self.PartitionAroundPivot(left, right, pivot_idx, nums)            if new_pivot_idx == k - 1:                return nums[new_pivot_idx]            elif new_pivot_idx > k - 1:                right = new_pivot_idx - 1            else:  # new_pivot_idx < k - 1.                left = new_pivot_idx + 1            def PartitionAroundPivot(self, left, right, pivot_idx, nums):        pivot_value = nums[pivot_idx]        new_pivot_idx = left        nums[pivot_idx], nums[right] = nums[right], nums[pivot_idx]        for i in xrange(left, right):            if nums[i] > pivot_value:                nums[i], nums[new_pivot_idx] = nums[new_pivot_idx], nums[i]                new_pivot_idx += 1                    nums[right], nums[new_pivot_idx] = nums[new_pivot_idx], nums[right]        return new_pivot_idx

C++: Sort

class Solution {public:    int findKthLargest(vector
& nums, int k) { sort(nums.begin(), nums.end()); return nums[nums.size() - k]; }};

C++: Priority queque

class Solution {    public:        int findKthLargest(vector
& nums, int k) { /** priority_queue
, less
> q; **/ priority_queue
> q; int len=nums.size(); for(int val:nums){ q.push(val); } while(q.size() > len-k+1){ q.pop(); } return q.top(); } };

 

C++: MaxHeap

class Solution {    public:        int findKthLargest(vector
& nums, int k) { //max heap method //min heap method //order statistics make_heap(nums.begin(), nums.end()); int result; for(int i=0; i

C++: Quick sort, partition

class Solution {public:    int findKthLargest(vector
& nums, int k) { int high = nums.size(); int low = 0; while (low < high) { int i = low; int j = high-1; int pivot = nums[low]; while (i <= j) { while (i <= j && nums[i] >= pivot) i++; while (i <= j && nums[j] < pivot) j--; if (i < j) swap(nums[i++],nums[j--]); } swap(nums[low],nums[j]); if (j == k-1) return nums[j]; else if (j < k-1) low = j+1; else high = j; } }};

  

  

  

 

转载于:https://www.cnblogs.com/lightwindy/p/8514845.html

你可能感兴趣的文章
如何有效的思考
查看>>
scala学习笔记:match与unapply()
查看>>
目录操作
查看>>
[MTK FP]如何通过ICON ID的value找到对应的ICON
查看>>
KindEditor在线HTML文本编辑器在asp.net中的使用
查看>>
Django的ORM实现数据库事务操作
查看>>
数理方程:Laplace变换 & 留数(更新中)
查看>>
Centos 6.9 install Python3.7
查看>>
laydate 显示结束时间不小于开始时间
查看>>
C# 网上收集的一些所谓的开源项目
查看>>
ASP.NET在IIS7中如何更改网站的.net framework框架版本
查看>>
6月19 琐碎知识点
查看>>
HTML5常用的方法
查看>>
第一个 MVC 应用程序(下半部分)
查看>>
urllib爬虫(流程+案例)
查看>>
JS基础_while的练习2
查看>>
Android开发中遇到的问题(二)——新建android工程的时候eclipse没有生成MainActivity和layout布局...
查看>>
Oracle O立方服务平台(O3SP)
查看>>
clion 查看代码 多次查看后如何一步一步回退到最初查看的代码位置
查看>>
PowerDesigner 参照完整性约束(级联删除)
查看>>