Skip to content

Commit fdec232

Browse files
committed
feat: add solutions to lc/lcof2 problems: Max XOR of Two Numbers in an Array
1 parent 91190d3 commit fdec232

File tree

11 files changed

+1269
-13
lines changed

11 files changed

+1269
-13
lines changed

lcof2/剑指 Offer II 067. 最大的异或/README.md

Lines changed: 317 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,22 +69,339 @@
6969

7070
<!-- 这里可写通用的实现逻辑 -->
7171

72+
哈希表或前缀树实现。
73+
7274
<!-- tabs:start -->
7375

7476
### **Python3**
7577

7678
<!-- 这里可写当前语言的特殊实现逻辑 -->
7779

7880
```python
81+
class Solution:
82+
def findMaximumXOR(self, nums: List[int]) -> int:
83+
max = 0
84+
mask = 0
85+
for i in range(30, -1, -1):
86+
current = 1 << i
87+
# 期望的二进制前缀
88+
mask = mask ^ current
89+
# 在当前前缀下, 数组内的前缀位数所有情况集合
90+
s = set()
91+
for num in nums:
92+
s.add(num & mask)
93+
# 期望最终异或值的从右数第i位为1, 再根据异或运算的特性推算假设是否成立
94+
flag = max | current
95+
for prefix in s:
96+
if prefix ^ flag in s:
97+
max = flag
98+
break
99+
return max
100+
```
79101

102+
```python
103+
class Trie:
104+
def __init__(self):
105+
self.left = None
106+
self.right = None
107+
108+
class Solution:
109+
def findMaximumXOR(self, nums: List[int]) -> int:
110+
self.root = Trie()
111+
self.highest = 30
112+
113+
def add(num):
114+
node = self.root
115+
for i in range(self.highest, -1, -1):
116+
bit = (num >> i) & 1
117+
if bit == 0:
118+
if node.left is None:
119+
node.left = Trie()
120+
node = node.left
121+
else:
122+
if node.right is None:
123+
node.right = Trie()
124+
node = node.right
125+
126+
def cal(num):
127+
node = self.root
128+
res = 0
129+
for i in range(self.highest, -1, -1):
130+
bit = (num >> i) & 1
131+
if bit == 0:
132+
if node.right:
133+
res = res * 2 + 1
134+
node = node.right
135+
else:
136+
res = res * 2
137+
node = node.left
138+
else:
139+
if node.left:
140+
res = res * 2 + 1
141+
node = node.left
142+
else:
143+
res = res * 2
144+
node = node.right
145+
return res
146+
147+
res = 0
148+
for i in range(1, len(nums)):
149+
add(nums[i - 1])
150+
res = max(res, cal(nums[i]))
151+
return res
80152
```
81153

82154
### **Java**
83155

84156
<!-- 这里可写当前语言的特殊实现逻辑 -->
85157

86158
```java
159+
class Solution {
160+
161+
public int findMaximumXOR(int[] numbers) {
162+
int max = 0;
163+
int mask = 0;
164+
for (int i = 30; i >= 0; i--) {
165+
int current = 1 << i;
166+
// 期望的二进制前缀
167+
mask = mask ^ current;
168+
// 在当前前缀下, 数组内的前缀位数所有情况集合
169+
Set<Integer> set = new HashSet<>();
170+
for (int j = 0, k = numbers.length; j < k; j++) {
171+
set.add(mask & numbers[j]);
172+
}
173+
// 期望最终异或值的从右数第i位为1, 再根据异或运算的特性推算假设是否成立
174+
int flag = max | current;
175+
for (Integer prefix : set) {
176+
if (set.contains(prefix ^ flag)) {
177+
max = flag;
178+
break;
179+
}
180+
}
181+
}
182+
return max;
183+
}
184+
}
185+
```
186+
187+
前缀树。
188+
189+
```java
190+
class Solution {
191+
private static final int HIGHEST = 30;
192+
private Trie root;
193+
194+
public int findMaximumXOR(int[] nums) {
195+
int res = 0;
196+
root = new Trie();
197+
for (int i = 1; i < nums.length; ++i) {
198+
add(nums[i - 1]);
199+
res = Math.max(res, cal(nums[i]));
200+
}
201+
return res;
202+
}
203+
204+
private int cal(int num) {
205+
Trie node = root;
206+
int res = 0;
207+
for (int i = HIGHEST; i >= 0; --i) {
208+
int bit = (num >> i) & 1;
209+
if (bit == 0) {
210+
if (node.right != null) {
211+
res = res * 2 + 1;
212+
node = node.right;
213+
} else {
214+
res = res * 2;
215+
node = node.left;
216+
}
217+
} else {
218+
if (node.left != null) {
219+
res = res * 2 + 1;
220+
node = node.left;
221+
} else {
222+
res = res * 2;
223+
node = node.right;
224+
}
225+
}
226+
}
227+
return res;
228+
}
229+
230+
private void add(int num) {
231+
Trie node = root;
232+
for (int i = HIGHEST; i >= 0; --i) {
233+
int bit = (num >> i) & 1;
234+
if (bit == 0) {
235+
if (node.left == null) {
236+
node.left = new Trie();
237+
}
238+
node = node.left;
239+
} else {
240+
if (node.right == null) {
241+
node.right = new Trie();
242+
}
243+
node = node.right;
244+
}
245+
}
246+
}
247+
}
248+
249+
class Trie {
250+
public Trie left;
251+
public Trie right;
252+
}
253+
```
254+
255+
### **C++**
256+
257+
```cpp
258+
class Trie {
259+
public:
260+
Trie* left;
261+
Trie* right;
262+
};
263+
264+
class Solution {
265+
public:
266+
int highest = 30;
267+
Trie* root;
268+
269+
int findMaximumXOR(vector<int>& nums) {
270+
root = new Trie();
271+
int res = 0;
272+
for (int i = 1; i < nums.size(); ++i)
273+
{
274+
add(nums[i - 1]);
275+
res = max(res, cal(nums[i]));
276+
}
277+
return res;
278+
}
279+
280+
int cal(int num) {
281+
Trie* node = root;
282+
int res = 0;
283+
for (int i = highest; i >= 0; --i)
284+
{
285+
int bit = (num >> i) & 1;
286+
if (bit == 0)
287+
{
288+
if (node->right)
289+
{
290+
res = res * 2 + 1;
291+
node = node->right;
292+
}
293+
else
294+
{
295+
res = res * 2;
296+
node = node->left;
297+
}
298+
}
299+
else
300+
{
301+
if (node->left)
302+
{
303+
res = res * 2 + 1;
304+
node = node->left;
305+
}
306+
else
307+
{
308+
res = res * 2;
309+
node = node->right;
310+
}
311+
}
312+
}
313+
return res;
314+
}
315+
316+
void add(int num) {
317+
Trie* node = root;
318+
for (int i = highest; i >= 0; --i)
319+
{
320+
int bit = (num >> i) & 1;
321+
if (bit == 0)
322+
{
323+
if (!node->left) node->left = new Trie();
324+
node = node->left;
325+
}
326+
else
327+
{
328+
if (!node->right) node->right = new Trie();
329+
node = node->right;
330+
}
331+
}
332+
}
333+
};
334+
```
87335
336+
### **Go**
337+
338+
```go
339+
const highest = 30
340+
341+
type trie struct {
342+
left, right *trie
343+
}
344+
345+
func (root *trie) add(num int) {
346+
node := root
347+
for i := highest; i >= 0; i-- {
348+
bit := (num >> i) & 1
349+
if bit == 0 {
350+
if node.left == nil {
351+
node.left = &trie{}
352+
}
353+
node = node.left
354+
} else {
355+
if node.right == nil {
356+
node.right = &trie{}
357+
}
358+
node = node.right
359+
}
360+
}
361+
}
362+
363+
func (root *trie) cal(num int) int {
364+
node := root
365+
res := 0
366+
for i := highest; i >= 0; i-- {
367+
bit := (num >> i) & 1
368+
if bit == 0 {
369+
if node.right != nil {
370+
res = res*2 + 1
371+
node = node.right
372+
} else {
373+
res = res * 2
374+
node = node.left
375+
}
376+
} else {
377+
if node.left != nil {
378+
res = res*2 + 1
379+
node = node.left
380+
} else {
381+
res = res * 2
382+
node = node.right
383+
}
384+
}
385+
}
386+
return res
387+
}
388+
389+
func findMaximumXOR(nums []int) int {
390+
root := &trie{}
391+
res := 0
392+
for i := 1; i < len(nums); i++ {
393+
root.add(nums[i-1])
394+
res = max(res, root.cal(nums[i]))
395+
}
396+
return res
397+
}
398+
399+
func max(a, b int) int {
400+
if a > b {
401+
return a
402+
}
403+
return b
404+
}
88405
```
89406

90407
### **...**

0 commit comments

Comments
 (0)