典型的topk问题

查找第K大的元素

http://www.nowcoder.com/questionTerminal/673454422d1b4a168aed31e449d87c00

想到第k大元素, 很明显就是topk问题
第k大就是要利用堆的特性

思路

维护一个k大小的最小堆, 然后把剩下的元素依次与堆顶进行比较, 如果大于堆顶就舍弃堆顶元素把更大的元素作为新堆顶, 然后向下调整维护堆的性质
时间复制度, 建堆 (k/2)log(k) , 维护第k大, (n-k)log(k), 最终时间复杂度 = O(nlog(k))
这个题中是第三大的元素, 所以k = 3

代码

Golang

package main

import (
    "bufio"
    "fmt"
    "os"
    "strconv"
    "strings"
)

var heap []int
var heapCap, heapSize = 0, 3

func main() {
    var num int
    heapSize = 3
    sc := bufio.NewScanner(os.Stdin)
    sc.Scan()
    str := sc.Text()
    heap = append(heap, 0)
    for _, numstr := range strings.Split(str[1:len(str)-1], ",") {
        num, _ = strconv.Atoi(numstr)
        heap = append(heap, num)
    }
    heapCap = len(heap) - 1
    makeHeap(heapSize)
    getTopK(heapSize)
    fmt.Println(heap[1])
}
// heapSize
func siftDown(i int) {
    var tmp int
    for i*2 <= heapSize {
        if heap[i] > heap[i*2] {
            tmp = i*2
        }else{
            tmp = i
        }
        if i*2+1 <= heapSize {
            if heap[tmp] > heap[i*2+1] {
                tmp = i*2+1
            }
        }
        if tmp != i {
            swap(tmp, i)
            i = tmp
        }else{
            break
        }
    }
}

func siftUp(tmp int) {
    for tmp != 1 {
        if heap[tmp] < heap[tmp/2] {
            swap(tmp, tmp/2)
        }
        tmp /= 2
    }
}

func makeHeap(size int) {
    for i := size; i > size/2; i-- {
        siftUp(i)
    }
}

func swap(a, b int) {
    heap[a], heap[b] = heap[b], heap[a]
}

func getTopK(k int) {
    for i:=k+1; i <= heapCap; i++ {
        if heap[i] > heap[1] {
            heap[1] = heap[i]
            siftDown(1)
        }
    }
}

Cpp

#include <bits/stdc++.h>

#define  ends " "
using namespace std;
int h[101] = {0};

int main() {
    int num = 0, k = 3;
    priority_queue<int, vector<int>, greater<int> > mHeap;
    while (getchar() != ']') {
        cin >> h[num++];
    }
    for(int i=0;i<k;i++) {
        mHeap.push(h[i]);
    }
    for(int i=k;i<num;i++){
        if (h[i]>mHeap.top()) {
            mHeap.pop();
            mHeap.push(h[i]);
        }
    }
    cout << mHeap.top() << endl;
    return 0;
}
全部评论

相关推荐

把球:这个听过,你加了就会发现是字节的hr
点赞 评论 收藏
分享
10-17 10:05
已编辑
北华大学 全栈开发
牛客872465272号:掉头发了哥
点赞 评论 收藏
分享
评论
点赞
收藏
分享
牛客网
牛客企业服务