由买买提看人间百态

boards

本页内容为未名空间相应帖子的节选和存档,一周内的贴子最多显示50字,超过一周显示500字 访问原贴
JobHunting版 - 贡献一道面试题目:找出在一个数组里面只出现1次的两个数字
相关主题
A家一道题大牛给个大数(+-*)的面试解答吧
如何求一个整数阶乘的各位数字和上一道我以前喜欢出的题目吧
一道位运算题Leetcode 上面的 Best Time to Buy and Sell Stock III
问一算法题F面经
找最大俩数的代码怎么写?问个面试题
一道要求常数空间和O(n)时间的排序题问一道前几天在版上看见的题
L家phone面,悲剧大整数相乘谁贴个bug free的code
三妹比三哥还威武啊今天竟然把MULTIPLY(大数相乘)写完了,发帖庆祝
相关话题的讨论汇总
话题: 数字话题: n1话题: 出现话题: 异或话题: n2
进入JobHunting版参与讨论
1 (共1页)
L*******o
发帖数: 895
1
题目:一个整型数组里除了两个数字之外,其他的数字都出现了两次。请写程序找出这
两个只出现一次的数字。要求时间复杂度是O(n),空间复杂度是O(1)。
分析:这是一道很新颖的关于位运算的面试题。
首先我们考虑这个问题的一个简单版本:一个数组里除了一个数字之外,其他的数字都
出现了两次。请写程序找出这个只出现一次的数字。
我们想到了异或运算的性质:任何一个数字异或它自己都等于0。也就是说,如果我们
从头到尾依次异或数组中的每一个数字,那么最终的结果刚好是那个只出现一次的数字
,因为那些出现两次的数字全部在异或中抵消掉了。
我们回到原始的问题。如果能够把原数组分为两个子数组。在每个子数组中,包含一个
只出现一次的数字,而其他数字都出现两次。如果能够这样拆分原数组,按照前面的办
法就是分别求出这两个只出现一次的数字了。
从头到尾依次异或数组中的每一个数字,那么最终得到的结果就是两个只出现一次的数
字的异或结果。因为其他数字都出现了两次,在异或中全部抵消掉了。由于这两个数字
肯定不一样,那么这个异或结果肯定不为0,也就是说在这个结果数字的二进制表示中
至少就有一位为1。我们在结果数字中找到第一个
g****7
发帖数: 1104
2
不明白为啥时间复杂度是O(n)

【在 L*******o 的大作中提到】
: 题目:一个整型数组里除了两个数字之外,其他的数字都出现了两次。请写程序找出这
: 两个只出现一次的数字。要求时间复杂度是O(n),空间复杂度是O(1)。
: 分析:这是一道很新颖的关于位运算的面试题。
: 首先我们考虑这个问题的一个简单版本:一个数组里除了一个数字之外,其他的数字都
: 出现了两次。请写程序找出这个只出现一次的数字。
: 我们想到了异或运算的性质:任何一个数字异或它自己都等于0。也就是说,如果我们
: 从头到尾依次异或数组中的每一个数字,那么最终的结果刚好是那个只出现一次的数字
: ,因为那些出现两次的数字全部在异或中抵消掉了。
: 我们回到原始的问题。如果能够把原数组分为两个子数组。在每个子数组中,包含一个
: 只出现一次的数字,而其他数字都出现两次。如果能够这样拆分原数组,按照前面的办

h****h
发帖数: 75
3
Smart.

【在 L*******o 的大作中提到】
: 题目:一个整型数组里除了两个数字之外,其他的数字都出现了两次。请写程序找出这
: 两个只出现一次的数字。要求时间复杂度是O(n),空间复杂度是O(1)。
: 分析:这是一道很新颖的关于位运算的面试题。
: 首先我们考虑这个问题的一个简单版本:一个数组里除了一个数字之外,其他的数字都
: 出现了两次。请写程序找出这个只出现一次的数字。
: 我们想到了异或运算的性质:任何一个数字异或它自己都等于0。也就是说,如果我们
: 从头到尾依次异或数组中的每一个数字,那么最终的结果刚好是那个只出现一次的数字
: ,因为那些出现两次的数字全部在异或中抵消掉了。
: 我们回到原始的问题。如果能够把原数组分为两个子数组。在每个子数组中,包含一个
: 只出现一次的数字,而其他数字都出现两次。如果能够这样拆分原数组,按照前面的办

z***e
发帖数: 5393
4
2n = O(n)

【在 g****7 的大作中提到】
: 不明白为啥时间复杂度是O(n)
c**********e
发帖数: 2007
5

Ask a weak question: how to do: 我们从头到尾依次异或数组中的每一个数字?

【在 L*******o 的大作中提到】
: 题目:一个整型数组里除了两个数字之外,其他的数字都出现了两次。请写程序找出这
: 两个只出现一次的数字。要求时间复杂度是O(n),空间复杂度是O(1)。
: 分析:这是一道很新颖的关于位运算的面试题。
: 首先我们考虑这个问题的一个简单版本:一个数组里除了一个数字之外,其他的数字都
: 出现了两次。请写程序找出这个只出现一次的数字。
: 我们想到了异或运算的性质:任何一个数字异或它自己都等于0。也就是说,如果我们
: 从头到尾依次异或数组中的每一个数字,那么最终的结果刚好是那个只出现一次的数字
: ,因为那些出现两次的数字全部在异或中抵消掉了。
: 我们回到原始的问题。如果能够把原数组分为两个子数组。在每个子数组中,包含一个
: 只出现一次的数字,而其他数字都出现两次。如果能够这样拆分原数组,按照前面的办

Y*****y
发帖数: 361
6
整体的idea很巧妙,但是实现的最后一步没完全明白。
假设那两个出现过一次的数是N1, N2。如果那些出现过两次的数在 indexOf1 这一位上
是1(或者0), 并且在array中出现在N1和N2之后,那num1和num2指的就不是N1和N2的
位置了吧。
j****w
发帖数: 6
7
同问。

【在 c**********e 的大作中提到】
:
: Ask a weak question: how to do: 我们从头到尾依次异或数组中的每一个数字?

c*****y
发帖数: 90
8
下面Code就是做这件事情的。
int resultExclusiveOR = 0;
for (int i = 0; i < length; i ++)
resultExclusiveOR ^= inputArray[i];

【在 c**********e 的大作中提到】
:
: Ask a weak question: how to do: 我们从头到尾依次异或数组中的每一个数字?

c*****y
发帖数: 90
9
LZ的方法很棒。对你的问题有些迷惑。以例子说明吧。
假设那两个出现过一次的数是N1, N2。那些出现过两次的数在indexOf1这一位上是1,
N1在indexOf1这一位上是1,则N2在indexOf1这一位上是0(与N1相反)。即使那些
出现过两次的数在array中出现在N1和N2之后,那么划分的时候它们全部会和N1划分在一起
(因为在indexOf1这一位上均是1)。这样,N1和N2被划分到不同的组,这样题目就被简化
为从各个组中找单个出现单次数的整数。

【在 Y*****y 的大作中提到】
: 整体的idea很巧妙,但是实现的最后一步没完全明白。
: 假设那两个出现过一次的数是N1, N2。如果那些出现过两次的数在 indexOf1 这一位上
: 是1(或者0), 并且在array中出现在N1和N2之后,那num1和num2指的就不是N1和N2的
: 位置了吧。

Y*****y
发帖数: 361
10
恩,这个分组idea我明白,不太明白的是code里面最后的实现。那里是用j作为index从
头扫到尾,然后对每个inputArray[j]进行判断,如果indexOf1这一位是1,update
temp1到inputArray[j],否则update temp2到inputArray[j]。最后的输出结果temp1和
temp2。
作为一个例子,假设N1,N2是出现过一次的数,且N1在那位上是1,N2是0。假设N3,N4出
现过两次,N3该位是1,N4是0。如果这个inputArray是这样的,{N3,N4,N1,N2,N3,N4},
用上面code里面的方法,最后temp1指向第二个N3,temp2指向第二个N4,得出的结果好
像不太对。 就算不用code里面的方法,我的疑问是,对这个例子,如何可以不重新排
序或空间复杂度是O(1),而直接把原来的数组分成两个组,且具有你说的那个性质(N1
和N2被划分到不同的组,每个组里面其他元素都出现两次)。
或者我的理解有问题,多谢指教。

在一起
被简化

【在 c*****y 的大作中提到】
: LZ的方法很棒。对你的问题有些迷惑。以例子说明吧。
: 假设那两个出现过一次的数是N1, N2。那些出现过两次的数在indexOf1这一位上是1,
: N1在indexOf1这一位上是1,则N2在indexOf1这一位上是0(与N1相反)。即使那些
: 出现过两次的数在array中出现在N1和N2之后,那么划分的时候它们全部会和N1划分在一起
: (因为在indexOf1这一位上均是1)。这样,N1和N2被划分到不同的组,这样题目就被简化
: 为从各个组中找单个出现单次数的整数。

m****n
发帖数: 145
11
smart solution!
c*****y
发帖数: 90
12
实际上分组是虚的,并没有重新排序呀。真正的操作是当indexOf1这一位是1的时候与
temp1进行XOR,而当indexOf1这一位是0,与temp2进行XOR。以你的例
子:temp1=N1^N3^N3=N1,temp2=N2^N4^N4=N2。这样结果就出来了。

},
N1

【在 Y*****y 的大作中提到】
: 恩,这个分组idea我明白,不太明白的是code里面最后的实现。那里是用j作为index从
: 头扫到尾,然后对每个inputArray[j]进行判断,如果indexOf1这一位是1,update
: temp1到inputArray[j],否则update temp2到inputArray[j]。最后的输出结果temp1和
: temp2。
: 作为一个例子,假设N1,N2是出现过一次的数,且N1在那位上是1,N2是0。假设N3,N4出
: 现过两次,N3该位是1,N4是0。如果这个inputArray是这样的,{N3,N4,N1,N2,N3,N4},
: 用上面code里面的方法,最后temp1指向第二个N3,temp2指向第二个N4,得出的结果好
: 像不太对。 就算不用code里面的方法,我的疑问是,对这个例子,如何可以不重新排
: 序或空间复杂度是O(1),而直接把原来的数组分成两个组,且具有你说的那个性质(N1
: 和N2被划分到不同的组,每个组里面其他元素都出现两次)。

Y*****y
发帖数: 361
13
哦,明白了,没有看见是XOR,看成赋值了……多谢一系列的耐心解答。

【在 c*****y 的大作中提到】
: 实际上分组是虚的,并没有重新排序呀。真正的操作是当indexOf1这一位是1的时候与
: temp1进行XOR,而当indexOf1这一位是0,与temp2进行XOR。以你的例
: 子:temp1=N1^N3^N3=N1,temp2=N2^N4^N4=N2。这样结果就出来了。
:
: },
: N1

b******g
发帖数: 1721
14
very good thinking process, admire....
1 (共1页)
进入JobHunting版参与讨论
相关主题
今天竟然把MULTIPLY(大数相乘)写完了,发帖庆祝找最大俩数的代码怎么写?
这道题怎么解一道要求常数空间和O(n)时间的排序题
来发个我的Leetcode的Python答案吧L家phone面,悲剧
发一个Startup的面经 - Affirm三妹比三哥还威武啊
A家一道题大牛给个大数(+-*)的面试解答吧
如何求一个整数阶乘的各位数字和上一道我以前喜欢出的题目吧
一道位运算题Leetcode 上面的 Best Time to Buy and Sell Stock III
问一算法题F面经
相关话题的讨论汇总
话题: 数字话题: n1话题: 出现话题: 异或话题: n2