zoukankan      html  css  js  c++  java
  • 亚马逊面试题目1

    准备面试过程中看到网上流传的一道亚马逊的面试题。认为很有意思,自己写了一遍code,如今和大家分享一下,题目例如以下:

    数组有N-2个数字,数字的范围为1 ... N,没有反复的元素,要求打印缺少的2个数字,不能够用额外的空间。


    方法1. 经过分析题目能够看出,数组中缺了两个数字,直观上能够通过把数字排序,然后从头到尾进行扫描。找到缺失的两个数字。由于有排序,而排序的时间复杂度最快为O(NLogN)。有没有更快的算法呢?

    方法2:数组中的数字事实上很有规律,有没有可能通过数学公式计算而非扫描来得到结果呢?假如我们把数组中全部的数字加起来得到一个总数 M0, 而1+2+3+4...+N = N(N+1)/2, 用后一个数字减去前一个数字的结果应该刚好是缺失的两个数字的加和。假定缺失的两个数字分别为x和y,则x+y= N(N+1)/2 - M0.

    我们得到了一个含有两个变量的方程式。有没有可能再得到一个关于这两个变量的另外一个方程式。从而通过联合两个方程式解出x和y? 

    如果我们尝试把数组中每个数组计算平方以后再加和在一起得到一个数字M1, 而1^2 + 2^2 + 3^2 + .... N^2 = N(N+1)(2N+1)/6, 把后一个数减去前一个便能够得到 x^2 + y^2 = N(N+1)(2N+1)/6 - M1

    这样我们便得到了两个关于x和y方程,通过联合这两个方程便能够解出x和y的值。


    方法3:假设N非常大,导致N^2 轻易就超出整数的表达范围,有没有可能得到其它其它关于x和y的一阶的方程? 在方法2中事实上我们非常easy便得到了x+y的值,假如我们 计算(x+y) / 2便能够得到一个介于x和y的中间的值,也就是说x一定小于等(x+y)/2, 而y一定大于 (x+y)/2

    假如我们在扫描数组进行加和过程中把加和的算法改为例如以下:

    假设 num[i] <= (x+y)/2

          total0 = total0 - num[i]

    否则

          total0 = total0 + num[i]    

    total0 的值是: N + N-1 + - 2 - .. - 1, 当中不包括x和y

    相同的原理。在计算1+2+3+4... + N的过程中把算法改成:

    假设i<= (x+y)/2

          total1 = total1 - i

    否则

          total1 = total1 + i

    total1 的值是: N + N-1 + y +.. - x - .. - 1


    而total1 - total0 = y - x

    这样我们便得到另外一个x和y的一阶方程式,联合方程式便可解出x和y。能够看出算法的时间复杂度为O(N), 而在方法2中,由于有计算数的平方即乘法。所以方法2的效率肯定低于方法3

    下面为代码


    void prtMissingNum(int * num, int len)
    {
        int i = 0;
        int totalPlus = 0;
        int totalMinus = 0;

        int index = 0;
        for(i = 0; i < len; i++)
        {
            totalPlus = totalPlus + (i+1) - num[i];
        }
        totalPlus = totalPlus + len + 1 + len + 2;

        index = totalPlus / 2;
        for(i = 0; i < len; i++)
        {
            if(i+1 <= index)
            {
                totalMinus = totalMinus - i -1;
            }
            else
            {
                totalMinus = totalMinus + i +1;
            }

            if(num[i] <= index)
            {
                totalMinus = totalMinus + num[i] ;
            }
            else
            {
                totalMinus = totalMinus - num[i] ;
            }
        }

        if(len + 1 <= index)
        {
            totalMinus = totalMinus - len - 1;
        }
        else
        {
            totalMinus = totalMinus + len + 1;
        }
        totalMinus = totalMinus + len + 2;

        // x + y = totalPlus
        // x - y = totalMinus
        int x = (totalPlus + totalMinus)/ 2;
        int y = (totalPlus - totalMinus)/ 2;

        printf("num1:%d, num2:%d ", x, y);

    }

  • 相关阅读:
    php CodeIgniter处理多环境错误级别配置
    bootstrap导航条在手机上默认展开二级目录,必须用setTimeout才能实现
    WordPress博客网站fonts.useso加载慢解决办法
    JS实现复制网页内容自动加入版权内容代码和原文链接
    bootstrap实现 手机端滑动效果,滑动到下一页,jgestures.js插件
    mysql字段varchar区分大小写utf8_bin、utf8_general_ci编码区别
    js捕捉IE窗口失去焦点事件,判断离开页面刷新或关闭的方法
    php防盗链,php ci在control里面控制除了自己站内的链接点击跳转,其他来源的都跳到站内页面
    php原子操作,文件锁flock,数据库事务
    默认只显示指定高度,出来按钮 阅读更多,加载全文,点击后显示全文的实现方式
  • 原文地址:https://www.cnblogs.com/gcczhongduan/p/5088409.html
Copyright © 2011-2022 走看看