在未排序的数组中找到第 k 个最大的元素

思路:

  基于堆的优先队列方法

  对于第K个,前K个,我们应该条件反射的想到优先队列。

  比如说此题的第K个最大元素,我们就可以维护一个长度为K的最小堆

  注:优先队列的底层是堆结构,根据题目情况构建最大堆或者最小堆,简单的记就是:

  如果是要前 K 个最大的元素,那就构造最小堆。(逻辑就是,要前 K 个最大值时,如果待添加的元素大于堆中的最小值,就可以添加。)

  如果是要前 K 个最小的元素,那就构造最大堆。(逻辑就是,要前 K 个最小值时,如果待添加的元素小于堆中的最大值,就可以添加。)

  1. 如果队列未满(size < k),直接添加
  2. 队列满时,如果读到的元素小于堆顶元素,不作处理;如果读到的元素大于堆顶元素,我们就将堆顶元素拿出,放入新元素
    package main
    
    import "container/heap"
    
    // go
    type TopList []int
    
    func (t TopList) Len() int {
    	return len(t)
    }
    
    func (t TopList) Less(i, j int) bool {
    	return t[i] < t[j]
    }
    
    func (t TopList) Swap(i, j int) {
    	t[i], t[j] = t[j], t[i]
    }
    
    func (t *TopList) Push(x interface{}) {
    	*t = append(*t, x.(int))
    }
    
    func (t *TopList) Pop() interface{} {
    	x := (*t)[len(*t)-1]
    	*t = (*t)[:len(*t)-1]
    	return x
    }
    
    func findKthLargest(nums []int, k int) int {
    	m := make(TopList, 0)
    	size := 0
    	for i := range nums {
    		if size < k {
    			heap.Push(&m, nums[i])
    			size++
    		} else {
    			if m[0] < nums[i] { //小顶堆 堆顶元素小于当前元素
    				heap.Pop(&m)
    				heap.Push(&m, nums[i])
    			}
    		}
    	}
    	return m[0]
    }
    
    func main() {
    	nums := []int{3,2,1,5,6,4}
    	k := 5
    	findKthLargest(nums, k)
    }
  3. https://mp.weixin.qq.com/s/iz1NxHeQ72vSrWs7abZrmQ     
  4. https://mp.weixin.qq.com/s?__biz=MzU1NjAyOTMyMQ==&mid=2247483861&idx=1&sn=6ab1032dcb0169d6fb4a9e663c79aa33&chksm=fbca0533ccbd8c25c161ca66d412fca220f3701f5f1e8ab7c641ecd2976292a3585a88f85b36&scene=21#wechat_redirect
  5. https://mp.weixin.qq.com/s?__biz=MzU1NjAyOTMyMQ==&mid=2247483843&idx=1&sn=af0a3cf1cae6b8065ebcc034817f4509&chksm=fbca0525ccbd8c3372158c98e04b6208c286954f1ec5a71d3c90227db32da667723ee6c21194&scene=21#wechat_redirect
posted @ 2020-07-07 10:24  small_lei_it  阅读(464)  评论(0编辑  收藏  举报