链接: http://discuss.joelonsoftware.com/default.asp?interview.11.614716
find the max value after XORing?
Give n 32bit numbers which are all unsigned integers, then find the two numbers that can get the maximum value after their XOR.
e.g.
for these numbers: 1, 2, 3, 4, 0xFFFFFFFE,
we should return 1 and 0xFFFFFFFE whose XOR result is the max.
please give a algorithm with time complexity <= nlgn, O(n)would be better.
e.g.
for these numbers: 1, 2, 3, 4, 0xFFFFFFFE,
we should return 1 and 0xFFFFFFFE whose XOR result is the max.
please give a algorithm with time complexity <= nlgn, O(n)would be better.
CSDN讨论地址:
http://topic.csdn.net/u/20100511/12/3044a051-4fad-40bc-b312-325fa4b7617a.html?19376
解法1:
I think the best approach to this would be a series of bucket sorts based on which bits of the numbers are set.
So you'd start by bucket-sorting the inputs according to their highest set bit. That is, the kth bucket gets all inputs between 2^k and 2^(k+1)-1. Now the highest-value (nonempty) bucket is guaranteed to contain one of your outputs.
Then, you'd want to sort the numbers in that bucket by their highest unset bit (after the first set one). If the highest value bucket of this second sort has a smallish number of elements, then you would start comparing them to the comparable bucket from your first sort, to find a maximal pair. If not, you could further sort them by the highest set bit after the highest unset bit. And so on.
For general data I think this would wind up close to O(N). But for perverse inputs I suspect you'd wind up doing around logN sorts. So it smells like an NlogN problem in the worst case.
Any of that sound right?
So you'd start by bucket-sorting the inputs according to their highest set bit. That is, the kth bucket gets all inputs between 2^k and 2^(k+1)-1. Now the highest-value (nonempty) bucket is guaranteed to contain one of your outputs.
Then, you'd want to sort the numbers in that bucket by their highest unset bit (after the first set one). If the highest value bucket of this second sort has a smallish number of elements, then you would start comparing them to the comparable bucket from your first sort, to find a maximal pair. If not, you could further sort them by the highest set bit after the highest unset bit. And so on.
For general data I think this would wind up close to O(N). But for perverse inputs I suspect you'd wind up doing around logN sorts. So it smells like an NlogN problem in the worst case.
Any of that sound right?
解法2:
I think this can be done in O(n).
I have a two-pass algorithm:
1. The first pass builds a binary tree.
. The tree has n leaves corresponding to the n given numbers.
. Each leaf has a depth of 32.
. When you add a leaf, you start from the MSB, if 0 go left, if 1 go right.
2. In the second pass, for each number x, bit reverse (m=~x) it first, and then find the best "match" of m in the tree.
The "match" looks like the following:
unsigned long BestMatch(unsigned long m, node * pRoot)
{
unsigned long match = 0;
for (int i=31; i>=0; i--)
{
match <<= 1;
BYTE bit = (m>>i)&0x01;
if (bit)
{
if (p->right)
{
p = p->right;
match ++;
}
else
{
p = p->left;
}
}
else
{
if (p->left)
{
p = p->left;
match ++;
}
else
{
p = p->right;
}
}
}
return match;
}
I have a two-pass algorithm:
1. The first pass builds a binary tree.
. The tree has n leaves corresponding to the n given numbers.
. Each leaf has a depth of 32.
. When you add a leaf, you start from the MSB, if 0 go left, if 1 go right.
2. In the second pass, for each number x, bit reverse (m=~x) it first, and then find the best "match" of m in the tree.
The "match" looks like the following:
unsigned long BestMatch(unsigned long m, node * pRoot)
{
unsigned long match = 0;
for (int i=31; i>=0; i--)
{
match <<= 1;
BYTE bit = (m>>i)&0x01;
if (bit)
{
if (p->right)
{
p = p->right;
match ++;
}
else
{
p = p->left;
}
}
else
{
if (p->left)
{
p = p->left;
match ++;
}
else
{
p = p->right;
}
}
}
return match;
}
收获:时间复杂度虽然 o(n) 要看着比 o(n*logn)好,但事实上有时候 o(n)实际上是o(k*n),而 k的大小并不一定比 log (n)好