程序员面试题精选(38):2008百度校园招聘的一道笔试题
2007-11-14 21:45
190 查看
题目大意如下:
一排N(最大1M)个正整数+1递增,乱序排列,第一个不是最小的,把它换成-1,最小数为a且未知求第一个被
-1替换掉的数原来的值,并分析算法复杂度。
解题思路:
一般稍微有点算法知识的人想想就会很容易给出以下解法:
设 Sn = a + (a+1) + (a+2) + .........+ (a+n-1) = na +n(n-1)/2
扫一次数组即可找到最小值a,时间复杂度O(n)
设 S = 修改第一项后所有数组项之和, 求和复杂度为O(n)
则被替换掉的第一项为 a1=Sn-S-1
总的时间复杂度为 O(1)+O(n)+O(n) = O(n)
根据该算法写出程序很简单,就不写了
主要是解题过程中没有太考虑题目中给的1M这个数字,一面的时候被问到求和溢出怎么办?
当时我一想,如果要考虑溢出,必然是要处理大数问题,以前没有看到大数就头疼……所以立马想了个绕过大数加法的方法,如下:
设定另外一个数组b
用 a, a+1,a+2....a+n-1依次分别减去原数组,得到的差放在该数组里,此求差过程复杂度为O(n)
对该数组各项求和即可得到Sn-S
面试官让证明一下我的设想,当时还没有给我纸和笔,用手在桌子上比划了一下没想出来,回来躺在床上想了一会就想出来了,也没什么难度:
相减求和后的数组,最差情况下应该是连续n/2个负数或者正数相加,如果不溢出,后面正负混合相加的话肯定不会溢出;这种情况下的最差特殊情况就是,原数列按照降序排列(除了第一项被替换掉了),而我们减时所用数列是增序排列。所得结果将是1个正数,n/2-1个负数,n/2个正数;而且我们相当于用最大的n/2个数减去最小的n/2个数,差值之和最大,取到了最差情况,我们只考虑后面一半求和的情况即可(前面有个-1不方便处理):
S(n/2) = (n-1) + (n-3) + (n-5)+ .....+ 1 (n为奇数时最后一项是0,不影响我们讨论数量级计算溢出)
= [(n-1)+1] * n/4 = n^2/4
题目中给定n最大为1M = 1024*1024
那么S(n/2)的最大量级为1024^4 = 2^40
而long long类型为64位,可以存放下该和,成功避免大数问题。
直接求和办法,一是和可能溢出,二是面试官要求把原始数组改称long long的话(即a可以也可能很大,求和时稍微加一下就会溢出)就得考虑大数求解了;而这种差值办法可以直接消掉a,求和只和n相关,和a无关。
一排N(最大1M)个正整数+1递增,乱序排列,第一个不是最小的,把它换成-1,最小数为a且未知求第一个被
-1替换掉的数原来的值,并分析算法复杂度。
解题思路:
一般稍微有点算法知识的人想想就会很容易给出以下解法:
设 Sn = a + (a+1) + (a+2) + .........+ (a+n-1) = na +n(n-1)/2
扫一次数组即可找到最小值a,时间复杂度O(n)
设 S = 修改第一项后所有数组项之和, 求和复杂度为O(n)
则被替换掉的第一项为 a1=Sn-S-1
总的时间复杂度为 O(1)+O(n)+O(n) = O(n)
根据该算法写出程序很简单,就不写了
主要是解题过程中没有太考虑题目中给的1M这个数字,一面的时候被问到求和溢出怎么办?
当时我一想,如果要考虑溢出,必然是要处理大数问题,以前没有看到大数就头疼……所以立马想了个绕过大数加法的方法,如下:
设定另外一个数组b
用 a, a+1,a+2....a+n-1依次分别减去原数组,得到的差放在该数组里,此求差过程复杂度为O(n)
对该数组各项求和即可得到Sn-S
面试官让证明一下我的设想,当时还没有给我纸和笔,用手在桌子上比划了一下没想出来,回来躺在床上想了一会就想出来了,也没什么难度:
相减求和后的数组,最差情况下应该是连续n/2个负数或者正数相加,如果不溢出,后面正负混合相加的话肯定不会溢出;这种情况下的最差特殊情况就是,原数列按照降序排列(除了第一项被替换掉了),而我们减时所用数列是增序排列。所得结果将是1个正数,n/2-1个负数,n/2个正数;而且我们相当于用最大的n/2个数减去最小的n/2个数,差值之和最大,取到了最差情况,我们只考虑后面一半求和的情况即可(前面有个-1不方便处理):
S(n/2) = (n-1) + (n-3) + (n-5)+ .....+ 1 (n为奇数时最后一项是0,不影响我们讨论数量级计算溢出)
= [(n-1)+1] * n/4 = n^2/4
题目中给定n最大为1M = 1024*1024
那么S(n/2)的最大量级为1024^4 = 2^40
而long long类型为64位,可以存放下该和,成功避免大数问题。
直接求和办法,一是和可能溢出,二是面试官要求把原始数组改称long long的话(即a可以也可能很大,求和时稍微加一下就会溢出)就得考虑大数求解了;而这种差值办法可以直接消掉a,求和只和n相关,和a无关。
相关文章推荐
- 程序员面试题精选(40):一道SPSS笔试题求解
- 百度校园2014招聘软件研发类笔试题(深圳站)
- 2012年腾讯招聘实习生一道笔试题
- 百度校园招聘的一道面试题
- 深信服科技公司2008校园招聘笔试题
- 我与西门子的面试全过程(一面+二面)_2008校园招聘_笔试与面试分享_UNUS.CN
- 一道容易出错的招聘笔试题
- 程序员面试题精选100题(38)-输出1到最大的N位数
- 百度2013年校园招聘一道笔试题--三位密码组合问题递归求解
- 阿里巴巴2014校园招聘笔试最后一道题目
- 2015百度校园实习生招聘笔试题整理
- 【校园招聘】一道笔试题看c++中virtual覆盖
- 求职的思考–我们应该展示什么_2008校园招聘网_实习与笔试面试经验_UNUS.CN
- 网新国际2008春季招聘笔试题 打印电话号码所对应的字符的所有可能组合
- 求职的思考–我们应该展示什么_2008校园招聘网_实习与笔试面试经验_UNUS.CN
- 程序员面试题精选(39):一道autodesk笔试题求解
- 对学生的建议:如何做好研究 | 2008校园招聘网 - 实习与笔试面试经验分享 - UNUS.CN
- 2012校园招聘的一道笔试题目
- 衣服不是最重要的–现场面试要注意的几个细节 | 2008校园招聘网 - 实习与笔试面试经验分享 - UNUS.CN
- 面试总结三---2015百度校园招聘长沙站前端工程师笔试面试经历