题目描述:
Given a non-empty array of numbers, a0, a1, a2, … , an-1, where 0 ≤ ai < 231.
Find the maximum result of ai XOR aj, where 0 ≤ i, j < n.
Could you do this in O(n) runtime?
Example:
1 2 3 4 5
| Input: [3, 10, 5, 25, 2, 8]
Output: 28
Explanation: The maximum result is 5 ^ 25 = 28.
|
这道题是使用递归的方法. 先找到出现不同的最高位, 然后按照该位是0还是1分为两类, 接下来处理下一位, 这时可以把数字分为4类, 分别以00
, 01
, 10
和11
开头, 最大的异或值会出现在00
与11
, 01
与10
两种组合中, 递归地处理接下来的位数.
有可能出现00
与11
, 01
与10
两种组合中每个组合都至少有一种分类是空的, 这个时候说明该位不可能为1, 只能为0, 可以用循环跳过这些位.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48
| class Solution { public: int findMaximumXOR(vector<int>& nums) { list<int> one, zero; int pos; for(pos = 31; pos >= 0; pos--){ one.clear(); zero.clear(); for(auto i : nums){ if(i & (1 << pos)) one.push_back(i); else zero.push_back(i); } if(!one.empty() && !zero.empty()) break; } if(one.empty() || zero.empty()) return 0; return (1 << pos) + findXORHelper(zero, one, pos - 1); } int findXORHelper(list<int> &zero, list<int> &one, int pos){ if(pos < 0) return 0; list<int> zeroZero, zeroOne, oneZero, oneOne; for(; pos >= 0; pos--){ zeroZero.clear(); zeroOne.clear(); oneZero.clear(); oneOne.clear(); for(auto i : zero){ if(i & (1 << pos)) zeroOne.push_back(i); else zeroZero.push_back(i); } for(auto i : one){ if(i & (1 << pos)) oneOne.push_back(i); else oneZero.push_back(i); } if(!((zeroZero.empty() || oneOne.empty()) && (oneZero.empty() || zeroOne.empty()))) break; } if(pos < 0) return 0; return (1 << pos) + max(findXORHelper(zeroZero, oneOne, pos - 1), findXORHelper(oneZero, zeroOne, pos - 1)); } };
|