• 面试题:1~ n1 有n个数,是有序的,找出重复的那个数。


    话说这道题有多种解法:
    第一种:数学解法
    举例
    1 2 3 4 = 10
    1 2 3 3 = 9
    那么我们可以计算出  4 - (10-9) = 3 则3是重复的。
    所以我们只要得到 1~ n-1 的和,就可以用高斯公式算出这个结果,但是前提是要知道和,那么遍历数组时间复杂度是O(n)。
    如果这个数列不是有序的,这个方法依然通用。

    第二种:折半查找法
    由于这个数列是有序的,所以用折半查找法是再合适不过了。
    array[n/2 -1] == n/2 ?不满足则往前找,满足往后找。时间复杂度是O(logn)

    第三种:折X份查找法 
    折多少份?这个很有趣,其中有一道面试题和这个题目类似。

    【题目】 话说有2个杯子,100层楼。 杯子可以在某层摔碎,用最少次测试出哪层(最底层)能摔碎杯子? 

    这个摔杯子可以从第一层一层层摔,最多100次,也可以2层2层摔,最多50次,也可以3层3层摔,最多33次。还能更快吗?
    中午吃饭的时候某同事说可以用二分法的反向思维来做 比如 2->4->8->16->32->64->100  这个跨度越来越大,最多也要30来次。虽然这个方法不是想要的结果,但给了我们一个启示就是 我们可以找一个比较合适的度。 比如直接找某楼摔,不行再回来,行了就可以省去很多层楼,这个思想很重要。

    如果我们累加呢?   1 3 6 10 15 21 28 36 45 55 66 78  91 100 这样最多是12+12=24次还能更快吗?
    反向过来递减?那么次数最多的则是第一次的那层! 14 27 39 50 60 69 77 84 90 95 99 ... omg 这。。。 还能更快吗?
    x+x*x >= 2n 那么,最优的次数是x 。
    找重复的那个数和摔杯子不完全一样,因为我们不是2个杯子只有2次摔碎的机会。我们有N次机会。 所以 我们如果测出14摔碎,可以直接 5 9 13-> 3 -> 1 这么摔。


            static void getRepeater(int s, int x, int n, int[] array)
            {
                
    if (x == 1)
                {
                    Console.Write(array[s 
    - 1]);
                    Console.Read();
                    
    return;
                }
                
    if (array[s - 1!= s)
                {
                    n 
    = x;
                    x 
    = getX(x);
                    s 
    -= x;
                    getRepeater(s, x, n, array);
                }
                
    else
                {
                    x
    --;
                    getRepeater(s 
    + x, x, n - x, array);
                }
            }
            
    static int getX(int n)
            {
                var x 
    = 1;
                
    while (x + x * x < 2 * n)
                {
                    x
    ++;
                }
                
    return x;
            }
            
    static void Main(string[] args)
            {
                
    int[] array = { 1234567891011,11121314151617181920 };
                
    int n = array.Length;
                
    int x = getX(n);
                
    int s = x;
                getRepeater(s, x, n, array);
            }

  • 相关阅读:
    ASP.NET Web API 控制器执行过程(一)
    ASP.NET Web API 控制器创建过程(二)
    ASP.NET Web API 控制器创建过程(一)
    ASP.NET Web API WebHost宿主环境中管道、路由
    ASP.NET Web API Selfhost宿主环境中管道、路由
    ASP.NET Web API 管道模型
    ASP.NET Web API 路由对象介绍
    ASP.NET Web API 开篇示例介绍
    ASP.NET MVC 视图(五)
    ASP.NET MVC 视图(四)
  • 原文地址:https://www.cnblogs.com/mad/p/1597642.html
Copyright © 2020-2023  润新知