輸出數組里面第N大的數


  好像有些大公司出過面試題:找出數組里面第N大的數,當然有點變化,但本質部分是這樣的.

  要求是不能排序,時間復雜度不能超過O(n^2)

 

  思路很多,我暫時就只會快排衍生的那種.如果對快速排序不太熟悉了,建議復習  我之前討論的快速排序.

  

  好的,現在假設你已經熟悉了快速排序.

  每輪快排,我們都得找個支點,然后從數組的兩邊交替開始和支點比較,右邊比支點小的數移到左邊,左邊比支點大的數移到右邊,移到最后,只剩一個位置了,然后把支點填進來.這時,你發現在支點右邊的數都比支點大.假設支點的index等於i,然后支點是第(endIndex-i+1)大的數了.(注意:endIndex是數組最后一個元素的下標)

  記住我們的目標,我們的目標是要找第N大的數,如果endIndex -i + 1 = n,就說明我們找到了.但是2個數比較有3種結果.我們來分情況討論下:

  記th = endIndex - i + 1,find(a, startIndex, endIndex, n)

  (1) th = n,返回支點

  (2) th > n,說明第n大的數在支點右邊,所以在右邊繼續找:find(a, i + 1, endIndex, n)

  (3) th < n,說明第n大的數在支點左邊,右邊的數都比要找的數大,也比支點大,所以只需要在左邊找第(n - th)大的數即可,find(a, startIndex, i - 1, n - th)

  

代碼:

#include<stdio.h>
#include<stdlib.h>


int choose_nth(int a[],int startIndex, int endIndex, int n);

int main(int argc, char *argv)
{
    int a[] = {150,111,1000,99,300,10,189};
    int n,i;
    int an = sizeof(a)/sizeof(int);
    
    printf("數組:\n");
    for(i = 0 ; i < an; ++i)
        printf("%d ",a[i]);
    printf("\n");
    
    printf("想找第幾大的數:");
    scanf("%d",&n);
    
    int ans = choose_nth(a, 0, an - 1, n);
    printf("第%d大的數是:%d\n", n, ans);
    return 0;
}

int choose_nth(int a[], int startIndex, int endIndex, int n)
{
    int midOne = a[startIndex];
    int i = startIndex, j = endIndex;
    if(i == j) //遞歸出口之一
        return a[i];

    if(i < j)
    {
        while(i < j)
        {
            for(; i < j; j--)
            if(a[j] < midOne)
            {
                a[i++] = a[j];
                break;
            }
            for(; i < j; i++)
            if(a[i] > midOne)
            {
                a[j--] = a[i];
                break;
            }
        }
        a[i] = midOne;//支點歸位

        int th = endIndex - i + 1;//計算下標為i的數第幾大

        if(th == n)//正好找到
        {
            return a[i];
        }
        else
        {
            if(th > n )//在支點右邊找
                return choose_nth(a, i + 1, endIndex, n);
            else//在支點左邊找第(n-th)大,因為右邊th個數都比支點大
                return choose_nth(a, startIndex, i - 1, n - th);
        }
    }
    
}

 

輸出結果:

數組:
150 111 1000 99 300 10 189 
想找第幾大的數:4
第4大的數是:150

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM