421. Maximum XOR of Two Numbers in an Array

这题要求On时间复杂度完成, 第一次做事没什么思路的, 答案网上有不贴了, 总结下这类题的思路.

不局限于这个题, 凡是对于这种给一个  数组,  求出 xxx 最大值的办法, 可能上来默认就是dp, 但是注意如果要求On复杂度, 毫无疑问是不能用dp的, 因为dp至少是On2了对吧.

那么需要处理的元素长度为N, 如何在On实现呢,   关键点在于" 反推" 的思路, 我这里反推的意思是 从结果推倒, 而不是通过数据一个个计算看是否满足结果.

举例,  一般DP题目就是使用 dp[x] 这样的变量来保存结果, 然后遍历所有数据完成得到答案, 把这种思路称之为正推法.

那么,  反过来, "遍历答案"  找出是否存在就是反推了.

以这题为例, 答案的解法是从最高位开始,一步步判断是否存在 a和b  使得 a^b 最大, 要一个int值最大,毫无疑问就是每位都是1, 

所以 用伪代码来表示思想就是

for i= 0xfffffff -> 0
      if exist   a ^ b = i   
           break;  

得到这个思想以后,  使用一个hash结构来保存所有的数组元素就可以变为On复杂度,  因为要求的是存在与否,  不需要顺序, hash就恰好解决了这个问题

首先得出基本思路

问题:  在数组A 里面求满足 xxx 条件的 最大/小 值  B ?   要求Ai ^ Aj = B

copy  A to   Hash<int> C
for max = 0xffffffff -> 1
    for Ai in A 
        for  Aj  in B
            if  Ai ^ Aj = max    return


这样有三重循环, 开始优化
for max = 0xffffffff -> 1  可变为按位处理  for  i = 32->1   , 32位整数, 从最高位开始处理
for Ai in A 
        for  Aj  in B    这有两重循环, 使用hash可以去掉一层循环

由于xor操作存在交换律  a^b=c  可以得到  a^c=b ;

最终结论  伪代码

max=0
mask=0
for i = 32 -> 1
  mask=mask| 1<<i mask得到第i位是1的数; 第一轮mask是 100000, 第二轮 11000  第三轮 1110000 ...
  for Ai in A  对数组的每个元素存储第i位
    Ai & 1<<i - >  hash  存入hash
  for hi in hash
    if max ^ hi  in hash  我们要求 a ^ b = 最大数,  反过来这里判断  最大数 ^ a 是否存在于hash
      更新max值
好了 这里 仍然有个 32到1 的循环, 由于是固定次数, 所以真正的循环只有for Ai in A  和  for hi in  hash , 两者没有嵌套关系, 也就是On复杂度了

  

猜你喜欢

转载自www.cnblogs.com/lychnis/p/9190653.html
今日推荐