hint:
求和
求平方和
取差
易得 n1-n2 和 n1^2-n2^2 即得 n1+n2, n1, n2
--
Alecs King
在 2011年7月12日 下午10:36,Ray Song <emac...@gmail.com> 写道:
把数组中所有元素和1到N异或一遍,得到的结果是n1^n2,且它肯定不是0,选取其中不为0的任一bit,根据其是否为0可以将数组元素划分为两组,当然也可以把1到N划分为两组,n1n2分别在这两组中,,接下来不用说了吧
Show me code! show me THE code!! show me MORE code!!!
------------------------------8<--------------------------------
#!/usr/bin/python
# please note that all numbers are processed sequentially.
# the following code stores all the original numbers in an array
# just for convenience of demo.
# sum method: one pass
# time O(n), space O(1)
# return (dup, miss)
def get1(n, a):
s = n*(n+1)/2
sq = n*(n+1)*(2*n+1)/6
for x in a:
s -= x
sq -= x*x
sq /= s
return (sq-s)/2, (sq+s)/2
# xor method: two pass
# time O(n), space O(1)
# return (dup, miss)
def get2(n, a):
s = 0
for x in xrange(n):
s ^= (x + 1) ^ a[x]
bit = 1
while (s & bit) == 0:
bit <<= 1
c1, c2 = 0, 0
x1, x2 = 0, 0
for x in xrange(n):
if a[x] & bit:
x1 ^= a[x]
c1 += 1
else:
x2 ^= a[x]
c2 += 1
if (x+1) & bit:
x1 ^= (x+1)
c1 -= 1
else:
x2 ^= (x+1)
c2 -= 1
if c1 == 1:
return x1, x2
else:
return x2, x1
# the stupid, fat but obviously correct method
# for checking answers
# time O(n), space O(n)
# return (dup, miss)
def get3(n, a):
hit = [0] * (n+1)
d, m = 0, 0
for x in a:
if hit[x]:
d = x
hit[x] += 1
for x in xrange(1, n + 1):
if hit[x] == 0:
m = x
break
return d, m
# quick & dirty tests
import random
r = random.Random()
def test():
n = r.randint(2, 10000)
a = range(1, n+1)
while True:
x, y = r.randint(1,n), r.randint(1,n)
if x != y:
a[x-1] = y
break
r.shuffle(a)
print get1(n, a) == get2(n, a) == get3(n, a)
print get1(5, [1,1,3,4,5])
print get2(5, [1,1,3,4,5])
print get3(5, [1,1,3,4,5])
for x in xrange(100):
test()
------------------------------>8--------------------------------
--
Alecs King
利用统计xor sum和个数的这个思路,不必二分。 :)
直接 xor 出来,随便找出1位划分。然后再跑一趟,分别 xor/计数即可。
python^W^W^W^W^Wseudo code 见另一封邮件。
--
Alecs King
仅靠这两个数值是解不出的。
比如 n1, n2 二进制表示只差一位的情况下:
n1 = abcdefg1xyz
n2 = abcdefg0xyz
abcdefgxyz 可为任意数值
--
Alecs King
s/W/H/g
--
Alecs King
On 7月12日, 下午9时33分, Beyond <beyond...@gmail.com> wrote:
> 偶然在网上看到这样一则问题,说是只要能说出解法,就通过了某公司面试第一关,与谷歌惯用的招聘方式有那边点相似,但非出自谷歌。招聘不招聘的,倒不感冒,个人 觉得解决该问题还是有点意思的,有兴趣的兄弟大可说说高见。
>
> 问题描述:
> 给定一个long
> long型的大整数N,有N个整数组成的数组,数组中每个整数n:1<=n<=N,并且仅出现一次,其中只有一个n1是重复的,即出现了两次,而有一个整数n2 不在数组中。求一种线性复杂度算法,能在较小不变的内存空间中,找到重复的整数n1和丢失的整数n2。
>
> 鄙人有种比较拙略的线性算法,如果大家对该topic有兴趣,随后交流。
On Jul 13, 12:30 am, Zhiming G <gaoz...@gmail.com> wrote:
> 找两种运算列方程组, 这两种运算需要有可计算的求和公式和O(1)的一次计算时间就行, 然后列方程:
>
> G(1..N) + g(n1, n2) = G(A[1]..A[N])
> F(1..N) + f(n1, n2) = F(A[1]..A[N])
>
> 其中F,G是两种常见操作, g和f是依赖G和F的已知表达式.
> 比如 F 是加法, G是平方和.
>
> 确定F/G时需要考虑一下解方程是否可解, 求解复杂度, 计算精度, 数字表示范围等~
>
> 2011/7/12 Alecs King <al...@perlchina.org>
>
>
>
>
>
>
>
> > On Tue, Jul 12, 2011 at 09:33:15PM +0800, Beyond wrote:
>
> > 偶然在网上看到这样一则问题,说是只要能说出解法,就通过了某公司面试第一关,与谷歌惯用的招聘方式有那边点相似,但非出自谷歌。招聘不招聘的,倒不感冒,个人觉得解决该问题还是有点意思的,有兴趣的兄弟大可说说高见。
>
> > > 问题描述:
> > > 给定一个long
>
> > long型的大整数N,有N个整数组成的数组,数组中每个整数n:1<=n<=N,并且仅出现一次,其中只有一个n1是重复的,即出现了两次,而有一个整数n2不在数组中。求一种线性复杂度算法,能在较小不变的内存空间中,找到重复的整数n1和丢失的整数n2。
>
> > > 鄙人有种比较拙略的线性算法,如果大家对该topic有兴趣,随后交流。
>
> > hint:
>
> > 求和
> > 求平方和
> > 取差
>
> > 易得 n1-n2 和 n1^2-n2^2 即得 n1+n2, n1, n2
>
> > --
> > Alecs King