寻找失去的图片数

据传说是MS/Google等等IT名企业的面试题:
有一组数字,从1到n,中减少了一个数,顺序也被打乱,放在一个n-1的数组里
请找出丢失的数字,最好能有程序,最好算法比较快
BTW1: 有很多种方法的哦,据说O(n)的方法就不止一种
BTW2: 扩展问题,如果丢失了2个数字呢?
BTW3: 一定要小心不要溢出,嗯,面试者有时候不会提醒你的
BTW4: 最好不要多申请n多空间
Update&一个很相近的题目:1-1000放在含有1001个元素的数组中,只有唯一的一个元素值重复,其它均只出现一次。每个数组元素只能访问一次,设计一个算法,将它找出来;不用辅助存储空间,能否设计一个算法实现?
现在这里给出一些解答:
第一题: 看到题目的第一反应就是把这个n-1个数字加起来,然后和1+2+3..+n的和进行比较,那个差值就是迷失的数字。但是这个方法正是BTW3里面提到的 不要溢出:)所以有一定的风险,还是不采用,还有人说用一个个+-来判断,可以是可以但是代码写起来也比较难看(个人感觉),还是异或操作符来的最合适一 些。 我们知道1^1=0;2^2=0;n^n=0;k^0=k;所以如果我们把这n-1个数字异或起来,再来异或一下1,2,..n。那么最终的答案肯定是迷 失数字k^(1^1)^(2^2)...^(n^n)。也就是K了。我们很容易地写下来了函数:
第二个问题来的更复杂一些,如果有两个数字迷失怎么办?还是方法一的方法,但是需要衍生一下。假定我们迷失的数字是S1,S2那么我们全部异或之后 得到的就是S1^S2只有的值。分析一下就可以知道,S1!=S2,也就是说S1^S2!=0; 这样也就是说S1^S2的这个值有二进制位有一位是1,那么我们就可以把这些所有的数字分成2组,一组这个二进制位是1,另一个这个二进制位是0的来重新 做异或。这样就可以吧其中一个S1求出来了,那再S1^(S1^S2)一下,S2也就得到了。类似地,我们写下了如下的代码:
还找了个test case 测试了一把:
看起来两个函数运行的结论是正确的。
后面的问题,Update确实如上所说的,非常类似,把这些个数字和1-1000异或就得到了答案了。奇数偶数的其实问题的第一二小题分别和迷失一个数字和两个数字对应,想法完全一致,这里不做展开了。
--------------------------------
1-N的自然数中,少了一个,找出这个数
O(n)空间的比较简单,下面给出几个个只需要1,2个额外变量的算法
(1)求和-容易溢出
S1=1+2+...+N=(N+1)N/2
然后遍历数列每次从S1中减去当前的数字
最后剩下的数字就是所求
为了防止溢出我们可以每次在S1大于一定的数字后,就去减,然后继续求和,再大于就继续减,以此类推。
Y1=1^2^3...^N
然后遍历数列每次异或当前的数字
最后剩下的就是要求的数字
实际上平时我们用的比较多的互逆运算有& 加/减&& 乘/除& 对数/幂数&
往往忽略了异或也是有一定的互逆性的
(3)O(N)时间的移动-排序
将a[i]移动到a[a[i]],使得数组有序
然后找出空着的位置
(4)O(NlogN)时间的移动-排序
用快排的思想,在1-N中选取游标X对数组快排一次,如果X被放在a[X-1]的位置上那么,要找的数字在X-N之间
否则X被放在a[X-2]的位置上 要找的数字在1-X-1之间&& 递归求解,直到找的要找的数字。
1-N个自然数,少了两个,找出这两个数
(1)求和-容易溢出
S1=1+2+...+N=(N+1)N/2
S2=1^2+2^2+...+N^2=(N+1)(2N+1)N/6
对于少了K个数的情况,如果K很少,我们可以找出K个和上面类似的函数,计算总体值,然后用解K元一次方程得到结果
但要注意函数的选择
按照上面同样的方法,求出最后的值P等于两个数的异或
确定P从低位到高位的第一个1是第i位
现在用快排的思想,将数列分成两个区间A和B
其中A中第i位是0,B中的第i位是1
然后调用问题1中的方法来分别求解A和B
(3)O(N)时间移动-排序
跟上面一样,实际上这种方法对于少了K个数的情况都能适用。
(4)O(NlogN)时间移动-排序
跟上面的方法一样
如果X被放在a[X-1]位置上,要找的两个数字在X-N之间
如果X被放在a[X-2]位置上,要找的数字一个在1-X-1间,一个在X-N之间
如果X被放在a[X-3]位置上,要找的数字都在1-X-1间
对于少了K个数字的情况,这种方法也可以做,但实现起来就比较复杂了
给你n个数,其中有且仅有一个数出现了奇数次,其余的数都出现了偶数次。用线性时间常数空间找出出现了奇数次的那一个数。
经过上面的介绍,应该想到异或
一个数跟自己偶数次异或是0
奇数次异或是自己
给你n个数,其中有且仅有两个数出现了奇数次,其余的数都出现了偶数次。用线性时间常数空间找出出现了奇数次的那两个数。
看看问题2和3中用异或的方法,应该知道答案了吧?
&&相关文章推荐
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:422017次
积分:5565
积分:5565
排名:第4981名
原创:56篇
转载:423篇
译文:34篇
评论:16条
(1)(1)(1)(1)(1)(2)(3)(2)(2)(1)(16)(1)(20)(77)(56)(14)(17)(26)(32)(37)(21)(47)(38)(4)(3)(1)(5)(6)(12)(25)(18)(4)(11)(7)
(window.slotbydup = window.slotbydup || []).push({
id: '4740881',
container: s,
size: '200,200',
display: 'inlay-fix'1776人阅读
面试(82)
给出一个包含 0 ..&N&中&N&个数的序列,找出0 ..&N&中没有出现在序列中的那个数。
您在真实的面试中是否遇到过这个题?&
N&=&4&且序列为&[0,
1, 3]&时,缺失的数为2。
可以改变序列中数的位置。
在数组上原地完成,使用O(1)的额外空间和O(N)的时间。
分析:感觉题目描述的不清晰,看起来是说0-N序列中只少了一个数,从样例猜测。。。于是就靠这种序列的和瞎做了一番。。。
class Solution {
* @param nums: a vector of integers
* @return: an integer
int findMissing(vector&int& &nums) {
// write your code here
int n = nums.size();
else if(n==1)
return nums[0]==0?1:0;
int sum = 0;
for(auto x:nums)
return (n)*(n+1)/2-
&&相关文章推荐
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:351075次
积分:4934
积分:4934
排名:第6022名
原创:148篇
评论:75条
(1)(24)(17)(43)(1)(1)(4)(3)(2)(2)(5)(2)(1)(2)(2)(4)(2)(6)(5)(2)(1)(2)(1)(4)(4)(5)(5)
(window.slotbydup = window.slotbydup || []).push({
id: '4740881',
container: s,
size: '200,200',
display: 'inlay-fix'扫二维码下载作业帮
2亿+学生的选择
下载作业帮安装包
扫二维码下载作业帮
2亿+学生的选择
寻找失去的数280.6-______+65.9=120&&&&&&&&&&147.5-(13.3+______)=12.5.
☆鹏管管☆s18
扫二维码下载作业帮
2亿+学生的选择
(1)120-65.9=54.1,280.6-54.1=226.5;(2)147.5-12.5=135,135-13.3=121.7.故答案为:226.5,121.7.
为您推荐:
(1)此题属于加减混合题,按照运算顺序,先算减法,再算加法,所以要求括号里的数;据此先用120-65.9,再用280.6减去此数即可;(2)此题属于有括号的混合题,按照运算顺序,先算括号里面的加法,再算括号外面的减法;据此要求括号里的数,可以先用147.5-12.5,再用此数减去13.3即可.
本题考点:
加法和减法的关系.
考点点评:
此题考查加、减法的关系及其应用.
扫描下载二维码

我要回帖

更多关于 重生之最强剑神 的文章

 

随机推荐