你得到一个和S和X,你需要找到,如果它存在两个数a和b使得a + b = S和a ^ b = X 我使用了一个循环到S / 2并检查它是否可能
for(int i=0;i<=s/2;i++)
{
if(i^(s-i)==X)
return true;
}
复杂性:O(n)
需要一些更好的方法
答案 0 :(得分:7)
鉴于a+b = (a XOR b) + (a AND b)*2
(from here)我们可以计算(a AND b)
:
如果S&lt; X =&gt;不可能,否则拿S-X。如果这是奇数=&gt;不可能,否则(a AND b)=(S-X)/ 2。
现在我们可以分别查看a和b的位。检查所有四种组合,我们看到只有一种结果是不可能的,即XOR和AND都是1。
因此,如果(一个XOR b)和(a AND b)!= 0则没有解决方案。否则,人们可以找到解决方程的a和b。
if (S < X) return false;
Y = S - X;
if (Y is odd) return false;
if ((X & (Y/2)) != 0) return false;
return true;
答案 1 :(得分:1)
如果没有先前的等式a+b = a^b + (a&b)*2
的知识,我们可以想到另一个解决方案。此解为O(logK)
,其中K是S和X的最大可能值。即,如果S和X为unsigned int
,则K为2^32 - 1
。
从S和X的MSB开始。有了这个位是否必须提供进位的信息,我们可以检查这个位,条件是右边的位是否应该提供进位。
案例1)总结一定不能提供随身携带
S X | need carry from right
------------------------------
0 0 | no (a = 0, b = 0)
0 1 | impossible
1 0 | yes (a = 0, b = 0)
1 1 | no (a = 1, b = 0 or 0,1)
S X | need carry from right
------------------------------
0 0 | no (a = 1, b = 1)
0 1 | yes (a = 1, b = 0 or 0,1)
1 0 | yes (a = 1, b = 1)
1 1 | impossible
MSB有一个特殊情况,其中进位并不重要。
案例3)不在乎
S X | need carry from right
------------------------------
0 0 | no (a = 0, b = 0 or 1,1)
0 1 | yes (a = 1, b = 0 or 0,1)
1 0 | yes (a = 0, b = 0 or 1,1)
1 1 | no (a = 1, b = 0 or 0,1)
最后,LSB必须以“不需要携带权利”结束。
实施和测试代码为here。它比较了已接受的解决方案和此解决方案的输出。
答案 2 :(得分:0)
我假设您假设您的输入序列已排序。
如果是,那么这个问题和找到给定和的对一样好,并且在检查它们的总和检查时(a ^ b == SUM)这应该足够了,这个问题可以在O(n)中解决。
URL
你不能做得更好。在最坏的情况下,您必须至少访问每个元素一次。