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


链接: 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)好

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值