zoukankan      html  css  js  c++  java
  • 输出数组里面第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("数组:
    ");
        for(i = 0 ; i < an; ++i)
            printf("%d ",a[i]);
        printf("
    ");
        
        printf("想找第几大的数:");
        scanf("%d",&n);
        
        int ans = choose_nth(a, 0, an - 1, n);
        printf("第%d大的数是:%d
    ", 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
  • 相关阅读:
    大数据Hadoop-2
    大数据Hadoop-1
    Consistent Hashing
    分支的创建、删除、切换、合并以及冲突解决
    windows WEB 高可用/可伸缩
    Oracle行转列、列转行的Sql语句总结
    从零到百亿互联网金融架构发展史---架构变迁
    WebJars
    springcloud(五):熔断监控Hystrix Dashboard和Turbine
    SpringBoot编写自定义的starter 专题
  • 原文地址:https://www.cnblogs.com/HpuAcmer/p/4141103.html
Copyright © 2011-2022 走看看