您的位置:首页 > 编程语言 > Go语言

有n个32位无符号整数,求其中异或之后结果最大的两个数

2010-05-14 16:28 274 查看


链接: 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.

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?

解法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;

  }

收获:时间复杂度虽然 o(n) 要看着比 o(n*logn)好,但事实上有时候 o(n)实际上是o(k*n),而 k的大小并不一定比 log (n)好
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
相关文章推荐