Skip to content

Commit 9f69c93

Browse files
authored
Merge pull request doocs#174 from Hinsteny/master
Add Solution.java for 421.Maximum XOR of Two Numbers in an Array
2 parents 200c45e + e3fcebc commit 9f69c93

File tree

3 files changed

+80
-1
lines changed

3 files changed

+80
-1
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
## 数组中两个数的最大异或值
2+
### 题目描述
3+
4+
给定一个非空数组,数组中元素为 a0, a1, a2, … , an-1,其中 0 ≤ ai < 2<sup>31</sup> 。
5+
6+
找到 ai 和aj 最大的异或 (XOR) 运算结果,其中0 ≤ i, j < n 。
7+
8+
**示例:**
9+
```
10+
输入: [3, 10, 5, 25, 2, 8]
11+
输出: 28
12+
解释: 最大的结果是 5 ^ 25 = 28.
13+
```
14+
15+
### 解法
16+
异或运算被称为不做进位的二进制加法运算, 且具有一个性质:如果 a ^ b = c 成立,那么a ^ c = b 与 b ^ c = a 均成立。
17+
18+
分析一下题目, 要在数组中找到两个数对他们进行异或运算后得到一个最大的异或值, 即这个异或值二进制表示非 0 最高位要尽可能的靠左同时剩余位尽可能为 1;
19+
20+
整体使用贪心原则, 依次假设整数从左至右第 i 为 1, 然后再使用一个 mask 与数组中所有数相与得到数据前 i 位的一个前缀集合, 再把之前一次 `i-1` 循环所得到的 max 加第 i 位
21+
为 1 得到当前 i 循环中期望的 `pre-max`, 再与前缀集合中的所有数进行异或运算, 如果得到的值也同时在集合中, 表示假设成立, `max` 变为 `pre-max`, 否则直接`i+1`进行下一个
22+
循环, 直到 `i=0` 算法结束。
23+
24+
```java
25+
class Solution {
26+
public int findMaximumXOR(int[] numbers) {
27+
int max = 0;
28+
int mask = 0;
29+
for (int i = 30; i >= 0; i--) {
30+
int current = 1 << i;
31+
// 期望的二进制前缀
32+
mask = mask ^ current;
33+
// 在当前前缀下, 数组内的前缀位数所有情况集合
34+
Set<Integer> set = new HashSet<>();
35+
for (int j = 0, k = numbers.length; j < k; j++) {
36+
set.add(mask & numbers[j]);
37+
}
38+
// 期望最终异或值的从右数第i位为1, 再根据异或运算的特性推算假设是否成立
39+
int flag = max | current;
40+
for (Integer prefix : set) {
41+
if (set.contains(prefix ^ flag)) {
42+
max = flag;
43+
break;
44+
}
45+
}
46+
}
47+
return max;
48+
}
49+
}
50+
```
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
class Solution {
2+
3+
public int findMaximumXOR(int[] numbers) {
4+
int max = 0;
5+
int mask = 0;
6+
for (int i = 30; i >= 0; i--) {
7+
int current = 1 << i;
8+
// 期望的二进制前缀
9+
mask = mask ^ current;
10+
// 在当前前缀下, 数组内的前缀位数所有情况集合
11+
Set<Integer> set = new HashSet<>();
12+
for (int j = 0, k = numbers.length; j < k; j++) {
13+
set.add(mask & numbers[j]);
14+
}
15+
// 期望最终异或值的从右数第i位为1, 再根据异或运算的特性推算假设是否成立
16+
int flag = max | current;
17+
for (Integer prefix : set) {
18+
if (set.contains(prefix ^ flag)) {
19+
max = flag;
20+
break;
21+
}
22+
}
23+
}
24+
return max;
25+
}
26+
}

‎solution/README.md

+4-1
Original file line numberDiff line numberDiff line change
@@ -765,6 +765,9 @@
765765
│   └── Solution.py
766766
├── 0415.Add Strings
767767
│   └── Solution.java
768+
├── 0421.Maximum XOR of Two Numbers in an Array
769+
│   ├── README.md
770+
│   └── Solution.java
768771
├── 0423.Reconstruct Original Digits from English
769772
│   └── Solution.cpp
770773
├── 0427.Construct Quad Tree
@@ -1056,4 +1059,4 @@
10561059
│   └── Solution.py
10571060
└── 5087.Letter Tile Possibilities
10581061
└── Solution.py
1059-
```
1062+
```

0 commit comments

Comments
 (0)