gaoming

我是高晓明

算法与数据结构面试分享(十八)一排N(最大1M)个正整数+1递增,乱序排列,第一个不是最小的,把它换成-1,最小数为a且未知求第一个被

这是百度的一道面试题。一排N(最大1M)个正整数+1递增,乱序排列,第一个不是最小的,把它换成-1,最小数为a且未知。求第一个被-1替换掉的数原来的值,并分析算法复杂度。

其实这道题并不难,关键是大家能否找出其中的陷阱并解决它。

理解问题:

1. 如果1-10的排序数组打乱顺序之后,我们拿掉其中一个并换成-1,大家能找出来吗?

2. 如果一个等差数列,打乱顺序后,我们拿掉其中一个并换成-1,大家能找出来吗?

3. 如果数据量很大,数据也很大,我们做加法会有问题吗?

从简单问题开始:

大家可以按照以上的思路来逐步优化问题。一般稍微有点算法知识的人想想就会很容易给出以下解法:

设 Sn = a + (a+1) + (a+2) + .........+ (a+n-1) = na +n(n-1)/2

所以替换之前是 Sn。 替换之后得到的S 里少了 a, 多以一个-1, 所以我们得到的Sn与S及a1的关系如下:S + a1 - (-1) = Sn, 即 a1 = Sn - S -1

复杂度为O(n),我们扫描一遍,找出最小的元素 a, 我们得到了S 对吧。

找陷阱,找解决办法

如果有问题,问题出在哪里呢?获取累加和S以及等差数列Sn时可能会出问题。这种问题我们之前就处理过,改加法为减法!!

我们假设构造了另外一个数组b[N]。 用 a, a+1,a+2....a+n-1依次分别减去原数组,得到的差放在该数组里,此求差过程复杂度为O(n), 并对该数组各项求和即可得到Sn-S。好了,如果可行的话,我们其实构造这个数组的必要都没有对吧,每次减去a + N呗,第一元素是a, 第二个a+1, 第三个a+2.

我们还需要证明下这种方法的可行性。

当两个数组元素对应做差的时候, 最差情况下应该是连续n/2个负数或者正数相加,如果不溢出,后面正负混合相加的话肯定不会溢出;这种情况下的最差特殊情况就是,原数列按照降序排列(除了第一项被替换掉了),而我们减时所用数列是增序排列。所得结果将是1个正数,n/2-1个负数,n/2个正数;

  • 原数组递减: n, n-1, n-2, n-3,....3,2,1
  • 新数组递增: 1, 2, 3, 4,..., n-2, n-1, n
  • 做差的数组: n-1, n-3, n-5, n-7,... 1, .... 3+n, 1+n,1-n

这种分析下,我们只用考虑一半的情况,并且替换第一个元素不考虑(因为这是极端的情况,没有替换的情况下都不出现问题,那接下来就不会出现问题了。)

再求做差数组的和

S(n/2) = (n-1) + (n-3) + (n-5)+ .....+ 1    = [(n-1)+1] * n/4 = n^2/4

题目中给定n最大为1M = 1024*1024

那么S(n/2)的最大量级为1024^4 = 2^40

而这个时候如果我们用long类型,即64位,可以存放下该和,我们就能避免溢出问题了。

好了,这道题我们就不上代码了哈。有问题欢迎大家留言。也欢迎大家关注我们的视频教程。

算法与数据结构

算法与数据结构-微软经典面试题

 


阅读更多
版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/gaoming201314/article/details/79964670
上一篇算法与数据结构面试分享(十七)两个单链表是否相交,若相交请求出交点
下一篇算法与数据结构面试分享(十九)判断两个字符串是否模式相似
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页

关闭
关闭