1. 703返回数据流中的第K大元素
设计一个找到数据流中第K大元素的类(class)。注意是排序后的第K大元素,不是第K个不同的元素。
你的 KthLargest 类需要一个同时接收整数 k 和整数数组nums 的构造器,它包含数据流中的初始元素。每次调用 KthLargest.add,返回当前数据流中第K大的元素。
示例:
int k = 3;
int[] arr = [4,5,8,2];
KthLargest kthLargest = new KthLargest(3, arr);
kthLargest.add(3); // returns 4
kthLargest.add(5); // returns 5
kthLargest.add(10); // returns 5
kthLargest.add(9); // returns 8
kthLargest.add(4); // returns 8
说明:
你可以假设 nums 的长度≥ k-1 且k ≥ 1。
##解法1,使用最小堆实现, 使用golang自带的最小堆,必须实现它下面的接口
/*******************/
type Interface interface {
sort.Interface
Push(x interface{}) // add x as element Len()
Pop() interface{} // remove and return element Len()
}
/******************/
type KthLargest struct {
kList []int
K int
}
func Constructor(k int, nums []int) KthLargest {
kl := KthLargest{
kList: make([]int,0,k),
K: k,
}
for _, v := range nums{
if kl.Len() < k {
heap.Push(&kl, v)
}else{
if v > kl.kList[0]{
heap.Push(&kl, v)
heap.Remove(&kl, 0)
}
}
}
return kl
}
func (this *KthLargest) Add(val int) int {
if this.Len() < this.K {
heap.Push(this, val)
}else{
if val > this.kList[0]{
heap.Push(this, val)
heap.Remove(this, 0)
}
}
return this.kList[0]
}
func(this *KthLargest) Len()int{
return len(this.kList)
}
func(this *KthLargest) Less(i,j int) bool{
return this.kList[i] < this.kList[j]
}
func(this *KthLargest) Swap(i,j int){
this.kList[i], this.kList[j] = this.kList[j], this.kList[i]
}
func(this *KthLargest) Push(x interface{}){
this.kList= append(this.kList, x.(int))
}
func(this *KthLargest) Pop() interface{}{
size := len(this.kList)
tail := this.kList[size-1]
this.kList = this.kList[0:size-1]
return tail
}
/**
* Your KthLargest object will be instantiated and called as such:
* obj := Constructor(k, nums);
* param_1 := obj.Add(val);
**/
##方法2,自己实现最小堆
type KthLargest struct {
heap *MinHeap
n int
}
func Constructor(k int, nums []int) KthLargest {
kth := KthLargest{heap:NewMinHeap(), n:k}
if len(nums) < k {
for _, num := range nums {
kth.heap.Push(num)
kth.n--
}
//kth.heap.Print()
return kth
}
for _, num := range nums[:k] {
kth.heap.Push(num)
kth.n--
}
for _, num := range nums[k:] {
if kth.heap.Peek() < num {
kth.heap.Pop()
kth.heap.Push(num)
}
}
return kth
}
func (this *KthLargest) Add(val int) int {
//fmt.Println(this.n)
//this.heap.Print()
if this.n > 0 {
this.heap.Push(val)
this.n--
return this.heap.Peek()
}
//this.heap.Print()
if this.heap.Peek() < val {
this.heap.Pop()
this.heap.Push(val)
}
return this.heap.Peek()
}
/**
* Your KthLargest object will be instantiated and called as such:
* obj := Constructor(k, nums);
* param_1 := obj.Add(val);
*/
type MinHeap struct {
nums []int
n int
}
func NewMinHeap() *MinHeap {
return &MinHeap{nums: make([]int, 0), n: 0}
}
func (h *MinHeap) shiftDown(pos int) {
n := h.n - 1
for 2*pos+1 <= n {
minChild := 2*pos + 1
if minChild < n && h.nums[minChild+1] < h.nums[minChild] {
minChild++
}
if h.nums[pos] < h.nums[minChild] {
return
}
h.nums[minChild], h.nums[pos] = h.nums[pos], h.nums[minChild]
pos = minChild
}
}
func (h *MinHeap) shiftUp(pos int) {
for pos > 0 && h.nums[pos] < h.nums[(pos-1)/2] {
h.nums[pos], h.nums[(pos-1)/2] = h.nums[(pos-1)/2], h.nums[pos]
pos = (pos - 1) / 2
}
}
func (h *MinHeap) Push(i int) {
h.nums = append(h.nums, i)
//fmt.Println('*', h.nums)
h.n++
h.shiftUp(h.n - 1)
//fmt.Println('-', h.nums)
}
func (h *MinHeap) Pop() int {
min := h.nums[0]
h.nums[0] = h.nums[h.n-1]
h.nums = h.nums[:(h.n-1)]
h.n--
h.shiftDown(0)
return min
}
func (h *MinHeap) Peek() int {
return h.nums[0]
}
func (h *MinHeap) Size() int {
return h.n
}
func (h *MinHeap) Print() {
fmt.Println(h.nums, h.n)
}
/*
["KthLargest","add","add","add","add","add"]
[[3,[4,5,8,2]],[3],[5],[10],[9],[4]]
["KthLargest","add","add","add","add","add"]
[[2,[0]],[-1],[1],[-2],[-4],[3]]
*/