Skip to content

Commit a2cf9b8

Browse files
committed
268
1 parent c427f1c commit a2cf9b8

File tree

2 files changed

+93
-0
lines changed

2 files changed

+93
-0
lines changed

SUMMARY.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -227,4 +227,5 @@
227227
* [260. Single Number III](leetcode-260-Single-NumberIII.md)
228228
* [263. Ugly Number](leetcode-263-Ugly-Number.md)
229229
* [264. Ugly Number II](leetcode-264-Ugly-NumberII.md)
230+
* [268. Missing Number](leetcode-268-Missing-Number.md)
230231
* [更多](more.md)

leetcode-268-Missing-Number.md

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
# 题目描述(简单难度)
2+
3+
![](https://windliang.oss-cn-beijing.aliyuncs.com/268.jpg)
4+
5+
`0``n` 中找到缺失的数字。
6+
7+
# 解法一
8+
9+
最直接的方法,把所有数字存到 `HashSet` 中,然后依次判断哪个数字不存在。
10+
11+
要注意的是数组的长度其实就等于题目中 `0, 1, ..., n` 中的 `n`
12+
13+
```java
14+
public int missingNumber(int[] nums) {
15+
HashSet<Integer> set = new HashSet<>();
16+
for (int n : nums) {
17+
set.add(n);
18+
}
19+
20+
//判断 0 到 n 中哪个数字缺失了
21+
for (int i = 0; i <= nums.length; i++) {
22+
if (!set.contains(i)) {
23+
return i;
24+
}
25+
}
26+
return -1;
27+
}
28+
```
29+
30+
# 解法二
31+
32+
[136 题](https://leetcode.wang/leetcode-136-Single-Number.html) 的解法二求和做差的方法记忆深刻,这里的话也可以用求和做差。
33+
34+
求出 `0``n` 的和,然后再计算原数组的和,做一个差就是缺失的数字了。
35+
36+
```java
37+
public int missingNumber(int[] nums) {
38+
int sum1 = 0;
39+
for (int n : nums) {
40+
sum1 += n;
41+
}
42+
// 等差公式计算 1 到 n 的和
43+
int sum2 = (1 + nums.length) * nums.length / 2;
44+
45+
return sum2 - sum1;
46+
}
47+
```
48+
49+
# 解法三
50+
51+
又到了神奇的异或的方法了,[这里](https://leetcode.com/problems/missing-number/discuss/69791/4-Line-Simple-Java-Bit-Manipulate-Solution-with-Explaination) 的解法。
52+
53+
[136 题](https://leetcode.wang/leetcode-136-Single-Number.html) 详细的介绍了异或的一个性质,`a ⊕ a = 0`,也就是相同数字异或等于 `0`
54+
55+
这道题的话,相当于我们有两个序列。
56+
57+
一个完整的序列, `0``n`
58+
59+
一个是 `0``n` 中缺少了一个数字的序列。
60+
61+
把这两个序列合在一起,其实就变成了[136 题](https://leetcode.wang/leetcode-136-Single-Number.html) 的题干——所有数字都出现了两次,只有一个数字出现了一次,找出这个数字。
62+
63+
假如合起来的数字序列是 `a b a b c c d``d` 出现了一次,也就是我们缺失的数字。
64+
65+
如果我们把给定的数字相互异或会发生什么呢?因为异或满足交换律和结合律,所以结果如下。
66+
67+
```java
68+
a ⊕ b ⊕ a ⊕ b ⊕ c ⊕ c ⊕ d
69+
= ( a ⊕ a ) ⊕ ( b ⊕ b ) ⊕ ( c ⊕ c ) ⊕ d
70+
= 000 ⊕ d
71+
= d
72+
```
73+
74+
这样我们就找了缺失的数字了。
75+
76+
代码的话,我们可以把下标当成上边所说的完整的序列。因为下标没有 `n`,所以初始化 `result = n`
77+
78+
然后把两个序列的数字依次异或即可。
79+
80+
```java
81+
public int missingNumber(int[] nums) {
82+
int result = nums.length;
83+
for (int i = 0; i < nums.length; i++) {
84+
result = result ^ nums[i] ^ i;
85+
}
86+
return result;
87+
}
88+
```
89+
90+
#
91+
92+
解法一和解法二的话都是可以直接想出来,解法三异或的方法其实也不难,但还是没形成惯性,没有往异或思考。

0 commit comments

Comments
 (0)