尋找第k大數字

Description

經過長時間的籌備工作,在Jourk,Ronny,Plipala,阿長,阿沈等人的努力下,DM實驗室建立起自己的系列網站,其中包括三個大板塊:DMOJ首頁、DMOJ論壇、DMOJ博客。

作爲一個大型的網站,數據的加工處理需要用到很多算法系統模塊,通過這些模塊對系統主數據庫進行修改。因此,在構建DMOJ系列網站的過程中,編寫了一個龐大的數據統計系統,其中包括一個尋找第k大數字的模塊,對於一個數據庫來說,這樣一個模塊的重要性不容置疑。但是,由於在修改網站的過程中,這個模塊被不慎刪掉了,DMOJ找到了聰明的你,希望你能幫DMOJ重寫這個模塊。

對於輸入數據,你將按數據要求找出n個數字中的第k大數字。

關於第k大數字的解釋:對於一個數字序列,計算該數字序列第k大數字,一種可行但效率不高的方法是,首先剔除數字序列中重複的數字,然後通過某種排序算法,獲得剔除重複數字後的數字序列從大到小排序的數字序列,然後取從大到小排序的數字序列的第k位的數字。從另一個角度,題目中的第k大數字即是不計入數字序列中數字重複出現的部分,對於數字重複出現的情況,應該認爲該數字只出現一次。

現在請聰明的你嘗試設計一種可行且效率更高的方法來解決這個問題。

不能使用algorithm的排序函數, 這道題TA會觀賞大家代碼,請重新提交

不用algorithm頭文件,有種方法可以做到2.62s, 希望大家能想辦法做得更快!

PS:

1、做了這個題以後面試遇到人家問怎麼找數組裏面的中位數就不要再說什麼先排序然後找中間那個數了

2、這個題網上有很多解法,也有人分析每種解法的時間複雜度,有興趣瞭解多少就多少

3、如果你瞭解了多種解法,那麼請分析,這些解法分別在什麼情況下會比較好?

    比如求中位數,哪種解法比較好?再比如求最大值,哪種方法比較好?

Input

輸入數據一共有三行。

第一行有一個正整數n(n<=10000000),表示一共給出多少個數字。

第二行有一個正整數k(k<=10000000),表示要求你找出第k大數字。

第三行有n個整數,給出n個數字。對於每個整數i,均滿足-10000000<=i<=10000000。

Output

    輸出文件共一行,包含一個整數,表示n個數字中第k大數字是多少。

Sample Input
3
2
2006 2007 2008
Sample Output
2007
Hint

不能使用algorithm的sort/qsort函數

使用快速排序:

// Problem#: 19589
// Submission#: 4960280
// The source code is licensed under Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License
// URI: http://creativecommons.org/licenses/by-nc-sa/3.0/
// All Copyright reserved by Informatic Lab of Sun Yat-sen University
#include<iostream>  
using namespace std;
int k;
int A[10000005];
int h[20000005]={0}; //h數組檢查重複或者用vector<bool>
void swap(int *a, int* b) {  
    if (a!= b) {
        *a= *a^ *b;
        *b= *a^ *b;
        *a= *a^ *b;
    }
}
int partion(int A[], int s, int e) {  
    int j= s- 1;
    for (int i= s; i< e; i++) {
        if (A[i]< A[e]&&i!= j) {
            j++;
            swap(&A[i], &A[j]);
        }
    }  
    swap(&A[j+ 1], &A[e]);
    return j+ 1;
}  
int qsort(int A[], int s, int e) {    
    int m= partion(A, s, e);
    if (m== k - 1) return A[m];
    else if (m> k -1) return qsort(A, s, m- 1);
    else return qsort(A, m+ 1, e);   
}
int main() {
    int n, temp, count = 0;
    cin>> n>> k;
    for (int i = 0; i< n; i++) {
        cin>> temp;
        if (!h[temp+ 10000000]) {
            h[temp + 10000000] = 1;
            A[count++] = temp;
        }
    }
    k = count - k + 1; //第K大數 
    cout<< qsort(A, 0, count- 1)<< endl;
}                                 






發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章