Skip to content

Commit 615e1e8

Browse files
authored
feat: add solutions to lc problem: No.0421 (doocs#1923)
No.0421.Maximum XOR of Two Numbers in an Array
1 parent 511780a commit 615e1e8

File tree

7 files changed

+408
-306
lines changed

7 files changed

+408
-306
lines changed

Diff for: solution/0400-0499/0421.Maximum XOR of Two Numbers in an Array/README.md

+113-109
Original file line numberDiff line numberDiff line change
@@ -41,153 +41,104 @@
4141

4242
<!-- 这里可写通用的实现逻辑 -->
4343

44-
**方法一:哈希表**
45-
46-
**方法二:前缀树**
44+
**方法一:前缀树**
4745

4846
题目是求两个元素的异或最大值,可以从最高位开始考虑。
4947

5048
我们把数组中的每个元素 $x$ 看作一个 $32$ 位的 $01$ 串,按二进制从高位到低位的顺序,插入前缀树(最低位为叶子节点)。
5149

52-
搜索 $x$ 时,尽量走相反的 $01$ 字符指针的策略,因为异或运算的法则是相同得 $0$,不同得 $1$,所以我们尽可能往与 $x$ 当前位相反的字符方向走,才能得到能和 $x$ 产生最大值的结果。
50+
搜索 $x$ 时,尽量走相反的 $01$ 字符指针的策略,因为异或运算的法则是相同得 $0$,不同得 $1$,所以我们尽可能往与 $x$ 当前位相反的字符方向走,才能得到能和 $x$ 产生最大异或值的结果。
51+
52+
时间复杂度 $O(n \times \log M)$,空间复杂度 $O(n \times \log M)$,其中 $n$ 是数组 $nums$ 的长度,而 $M$ 是数组中元素的最大值。
5353

5454
<!-- tabs:start -->
5555

5656
### **Python3**
5757

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

60-
```python
61-
class Solution:
62-
def findMaximumXOR(self, nums: List[int]) -> int:
63-
max = 0
64-
mask = 0
65-
for i in range(30, -1, -1):
66-
current = 1 << i
67-
# 期望的二进制前缀
68-
mask = mask ^ current
69-
# 在当前前缀下, 数组内的前缀位数所有情况集合
70-
s = set()
71-
for num in nums:
72-
s.add(num & mask)
73-
# 期望最终异或值的从右数第i位为1, 再根据异或运算的特性推算假设是否成立
74-
flag = max | current
75-
for prefix in s:
76-
if prefix ^ flag in s:
77-
max = flag
78-
break
79-
return max
80-
```
81-
8260
```python
8361
class Trie:
62+
__slots__ = ("children",)
63+
8464
def __init__(self):
85-
self.children = [None] * 2
65+
self.children: List[Trie | None] = [None, None]
8666

87-
def insert(self, x):
67+
def insert(self, x: int):
8868
node = self
8969
for i in range(30, -1, -1):
90-
v = (x >> i) & 1
70+
v = x >> i & 1
9171
if node.children[v] is None:
9272
node.children[v] = Trie()
9373
node = node.children[v]
9474

95-
def search(self, x):
75+
def search(self, x: int) -> int:
9676
node = self
97-
res = 0
77+
ans = 0
9878
for i in range(30, -1, -1):
99-
v = (x >> i) & 1
79+
v = x >> i & 1
10080
if node.children[v ^ 1]:
101-
res = res << 1 | 1
81+
ans |= 1 << i
10282
node = node.children[v ^ 1]
10383
else:
104-
res <<= 1
10584
node = node.children[v]
106-
return res
85+
return ans
10786

10887

10988
class Solution:
11089
def findMaximumXOR(self, nums: List[int]) -> int:
11190
trie = Trie()
112-
for v in nums:
113-
trie.insert(v)
114-
return max(trie.search(v) for v in nums)
91+
for x in nums:
92+
trie.insert(x)
93+
return max(trie.search(x) for x in nums)
11594
```
11695

11796
### **Java**
11897

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

121100
```java
122-
class Solution {
123-
124-
public int findMaximumXOR(int[] numbers) {
125-
int max = 0;
126-
int mask = 0;
127-
for (int i = 30; i >= 0; i--) {
128-
int current = 1 << i;
129-
// 期望的二进制前缀
130-
mask = mask ^ current;
131-
// 在当前前缀下, 数组内的前缀位数所有情况集合
132-
Set<Integer> set = new HashSet<>();
133-
for (int j = 0, k = numbers.length; j < k; j++) {
134-
set.add(mask & numbers[j]);
135-
}
136-
// 期望最终异或值的从右数第i位为1, 再根据异或运算的特性推算假设是否成立
137-
int flag = max | current;
138-
for (Integer prefix : set) {
139-
if (set.contains(prefix ^ flag)) {
140-
max = flag;
141-
break;
142-
}
143-
}
144-
}
145-
return max;
146-
}
147-
}
148-
```
101+
class Trie {
102+
private Trie[] children = new Trie[2];
149103

150-
前缀树:
104+
public Trie() {
151105

152-
```java
153-
class Trie {
154-
Trie[] children = new Trie[2];
106+
}
155107

156-
void insert(int x) {
108+
public void insert(int x) {
157109
Trie node = this;
158110
for (int i = 30; i >= 0; --i) {
159-
int v = (x >> i) & 1;
111+
int v = x >> i & 1;
160112
if (node.children[v] == null) {
161113
node.children[v] = new Trie();
162114
}
163115
node = node.children[v];
164116
}
165117
}
166118

167-
int search(int x) {
119+
public int search(int x) {
168120
Trie node = this;
169-
int res = 0;
121+
int ans = 0;
170122
for (int i = 30; i >= 0; --i) {
171-
int v = (x >> i) & 1;
123+
int v = x >> i & 1;
172124
if (node.children[v ^ 1] != null) {
173-
res = res << 1 | 1;
125+
ans |= 1 << i;
174126
node = node.children[v ^ 1];
175127
} else {
176-
res <<= 1;
177128
node = node.children[v];
178129
}
179130
}
180-
return res;
131+
return ans;
181132
}
182133
}
183134

184135
class Solution {
185136
public int findMaximumXOR(int[] nums) {
186137
Trie trie = new Trie();
187138
int ans = 0;
188-
for (int v : nums) {
189-
trie.insert(v);
190-
ans = Math.max(ans, trie.search(v));
139+
for (int x : nums) {
140+
trie.insert(x);
141+
ans = Math.max(ans, trie.search(x));
191142
}
192143
return ans;
193144
}
@@ -199,34 +150,35 @@ class Solution {
199150
```cpp
200151
class Trie {
201152
public:
202-
vector<Trie*> children;
203-
string v;
153+
Trie* children[2];
154+
204155
Trie()
205-
: children(2) {}
156+
: children{nullptr, nullptr} {}
206157

207158
void insert(int x) {
208159
Trie* node = this;
209160
for (int i = 30; ~i; --i) {
210-
int v = (x >> i) & 1;
211-
if (!node->children[v]) node->children[v] = new Trie();
161+
int v = x >> i & 1;
162+
if (!node->children[v]) {
163+
node->children[v] = new Trie();
164+
}
212165
node = node->children[v];
213166
}
214167
}
215168

216169
int search(int x) {
217170
Trie* node = this;
218-
int res = 0;
171+
int ans = 0;
219172
for (int i = 30; ~i; --i) {
220-
int v = (x >> i) & 1;
173+
int v = x >> i & 1;
221174
if (node->children[v ^ 1]) {
222-
res = res << 1 | 1;
175+
ans |= 1 << i;
223176
node = node->children[v ^ 1];
224177
} else {
225-
res <<= 1;
226178
node = node->children[v];
227179
}
228180
}
229-
return res;
181+
return ans;
230182
}
231183
};
232184

@@ -235,9 +187,9 @@ public:
235187
int findMaximumXOR(vector<int>& nums) {
236188
Trie* trie = new Trie();
237189
int ans = 0;
238-
for (int v : nums) {
239-
trie->insert(v);
240-
ans = max(ans, trie->search(v));
190+
for (int x : nums) {
191+
trie->insert(x);
192+
ans = max(ans, trie->search(x));
241193
}
242194
return ans;
243195
}
@@ -248,51 +200,103 @@ public:
248200
249201
```go
250202
type Trie struct {
251-
children [26]*Trie
203+
children [2]*Trie
252204
}
253205
254206
func newTrie() *Trie {
255207
return &Trie{}
256208
}
257209
258-
func (this *Trie) insert(x int) {
259-
node := this
210+
func (t *Trie) insert(x int) {
211+
node := t
260212
for i := 30; i >= 0; i-- {
261-
v := (x >> i) & 1
213+
v := x >> i & 1
262214
if node.children[v] == nil {
263215
node.children[v] = newTrie()
264216
}
265217
node = node.children[v]
266218
}
267219
}
268220
269-
func (this *Trie) search(x int) int {
270-
node := this
271-
res := 0
221+
func (t *Trie) search(x int) int {
222+
node := t
223+
ans := 0
272224
for i := 30; i >= 0; i-- {
273-
v := (x >> i) & 1
225+
v := x >> i & 1
274226
if node.children[v^1] != nil {
275-
res = res<<1 | 1
227+
ans |= 1 << i
276228
node = node.children[v^1]
277229
} else {
278-
res <<= 1
279230
node = node.children[v]
280231
}
281232
}
282-
return res
233+
return ans
283234
}
284235
285-
func findMaximumXOR(nums []int) int {
236+
func findMaximumXOR(nums []int) (ans int) {
286237
trie := newTrie()
287-
ans := 0
288-
for _, v := range nums {
289-
trie.insert(v)
290-
ans = max(ans, trie.search(v))
238+
for _, x := range nums {
239+
trie.insert(x)
240+
ans = max(ans, trie.search(x))
291241
}
292242
return ans
293243
}
294244
```
295245

246+
### **Rust**
247+
248+
```rust
249+
struct Trie {
250+
children: [Option<Box<Trie>>; 2],
251+
}
252+
253+
impl Trie {
254+
fn new() -> Trie {
255+
Trie {
256+
children: [None, None],
257+
}
258+
}
259+
260+
fn insert(&mut self, x: i32) {
261+
let mut node = self;
262+
for i in (0..=30).rev() {
263+
let v = (x >> i & 1) as usize;
264+
if node.children[v].is_none() {
265+
node.children[v] = Some(Box::new(Trie::new()));
266+
}
267+
node = node.children[v].as_mut().unwrap();
268+
}
269+
}
270+
271+
fn search(&self, x: i32) -> i32 {
272+
let mut node = self;
273+
let mut ans = 0;
274+
for i in (0..=30).rev() {
275+
let v = (x >> i & 1) as usize;
276+
if let Some(child) = &node.children[v ^ 1] {
277+
ans |= 1 << i;
278+
node = child.as_ref();
279+
} else {
280+
node = node.children[v].as_ref().unwrap();
281+
}
282+
}
283+
ans
284+
}
285+
}
286+
287+
impl Solution {
288+
pub fn find_maximum_xor(nums: Vec<i32>) -> i32 {
289+
let mut trie = Trie::new();
290+
let mut ans = 0;
291+
for &x in nums.iter() {
292+
trie.insert(x);
293+
ans = ans.max(trie.search(x));
294+
}
295+
ans
296+
}
297+
}
298+
```
299+
296300
### **...**
297301

298302
```

0 commit comments

Comments
 (0)