输出数组里面第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

 

posted @ 2014-12-03 20:04  开开甲  阅读(5088)  评论(0编辑  收藏  举报