Skip to content

Commit c4a2959

Browse files
committed
ADD 268
1 parent a372d1c commit c4a2959

File tree

2 files changed

+126
-0
lines changed

2 files changed

+126
-0
lines changed

Readme.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@
6161
| 231 | [2的幂](https://github.com/MisterBooo/LeetCodeAnimation/tree/master/notes/LeetCode第231号问题:2的幂.md) |
6262
| 237 | [删除链表中的节点](https://github.com/MisterBooo/LeetCodeAnimation/tree/master/notes/LeetCode第237号问题:删除链表中的节点.md) |
6363
| 239 | [滑动窗口最大值](https://github.com/MisterBooo/LeetCodeAnimation/tree/master/notes/LeetCode第239号问题:滑动窗口最大值.md) |
64+
| 268 | [缺失数字](https://github.com/MisterBooo/LeetCodeAnimation/tree/master/notes/LeetCode第268号问题:缺失数字.md) |
6465
| 279 | [完全平方数](https://github.com/MisterBooo/LeetCodeAnimation/tree/master/notes/LeetCode第279号问题:完全平方数.md) |
6566
| 283 | [移动零](https://github.com/MisterBooo/LeetCodeAnimation/tree/master/notes/LeetCode第283号问题:移动零.md) |
6667
| 295 | [数据流的中位数](https://github.com/MisterBooo/LeetCodeAnimation/tree/master/notes/LeetCode第295号问题:数据流的中位数.md) |
Lines changed: 125 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,125 @@
1+
# LeetCode 第 268 号问题:缺失数字
2+
3+
> 本文首发于公众号「五分钟学算法」,是[图解 LeetCode ](<https://github.com/MisterBooo/LeetCodeAnimation>)系列文章之一。
4+
>
5+
> 个人网站:[https://www.cxyxiaowu.com](https://www.cxyxiaowu.com)
6+
7+
今天分享一道很简单的算法题。
8+
9+
题目来源于 LeetCode 上第 268 号问题:缺失数字。题目难度为 Easy,目前通过率为 50.2% 。
10+
11+
## 题目描述
12+
13+
给定一个包含 `0, 1, 2, ..., n`*n* 个数的序列,找出 0 .. *n* 中没有出现在序列中的那个数。
14+
15+
**说明:**
16+
17+
你的算法应该具有线性时间复杂度。 你可以不使用额外空间来实现吗?
18+
19+
![](https://raw.githubusercontent.com/MisterBooo/myBlogPic/master/20190516113448.png)
20+
21+
## 题目解析
22+
23+
这道题目有三种解法。
24+
25+
### 解法一:异或法
26+
27+
和之前那道 **只出现一次的数字** 很类似:
28+
29+
> 只出现一次的数字: 给定一个**非空**整数数组,除了某个元素只出现一次以外,其余每个元素均出现两次。找出那个只出现了一次的元素。
30+
31+
如果我们补充一个完整的数组和原数组进行组合,那所求解的问题就变成了 **只出现一次的数字**
32+
33+
将少了一个数的数组与 0 到 n 之间完整的那个数组进行异或处理,因为相同的数字异或会变为了 0 ,那么全部数字异或后,剩下的就是少了的那个数字。
34+
35+
![](https://raw.githubusercontent.com/MisterBooo/myBlogPic/master/20190516143539.png)
36+
37+
#### 代码实现1
38+
39+
```java
40+
class Solution {
41+
public int missingNumber(int[] nums) {
42+
int res = 0;
43+
//注意数组越界情况
44+
for (int i = 0; i < nums.length;i++){
45+
// i 表示完整数组中的数字,与原数组中的数字 nums[i] 进行异或,再与保存的结果异或
46+
res = res^i^nums[i];
47+
}
48+
//最后需要与循环中无法使用到的那个最大的数异或
49+
return res^i;
50+
}
51+
}
52+
```
53+
54+
#### 代码实现2
55+
56+
```java
57+
class Solution {
58+
public int missingNumber(int[] nums) {
59+
int res = nums.length;
60+
for (int i = 0; i < nums.length; ++i){
61+
res ^= nums[i];
62+
res ^= i;
63+
}
64+
return res;
65+
}
66+
}
67+
```
68+
69+
70+
71+
### 解法二:求和法
72+
73+
- 求出 0 到 n 之间所有的数字之和
74+
- 遍历数组计算出原始数组中数字的累积和
75+
- 两和相减,差值就是丢失的那个数字
76+
77+
![](https://raw.githubusercontent.com/MisterBooo/myBlogPic/master/20190516151203.gif)
78+
79+
```java
80+
//小吴之前担心会数据溢出,不过估计这题考察的不是这个,所以测试用例没写这种吧,还是能 AC 的
81+
class Solution {
82+
public int missingNumber(int[] nums) {
83+
int n = nums.length;
84+
int sum = (n+0)*(n+1)/2;
85+
for (int i=0; i<n; i++){
86+
sum -= nums[i];
87+
}
88+
return sum;
89+
}
90+
}
91+
```
92+
93+
94+
95+
### 解法三:二分法
96+
97+
将数组进行排序后,利用二分查找的方法来找到缺少的数字,注意搜索的范围为 0 到 n 。
98+
99+
- 首先对数组进行排序
100+
- 用元素值和下标值之间做对比,如果元素值大于下标值,则说明缺失的数字在左边,此时将 right 赋为 mid ,反之则将 left 赋为 mid + 1 。
101+
102+
> 注:由于一开始进行了排序操作,因此使用二分法的性能是不如上面两种方法。
103+
104+
```java
105+
public class Solution {
106+
public int missingNumber(int[] nums) {
107+
Arrays.sort(nums);
108+
int left = 0;
109+
int right = nums.length;
110+
while (left < right){
111+
int mid = (left + right) / 2;
112+
if (nums[mid] > mid){
113+
right = mid;
114+
}else{
115+
left = mid + 1;
116+
}
117+
}
118+
return left;
119+
}
120+
}
121+
```
122+
123+
124+
125+
![](https://bucket-1257126549.cos.ap-guangzhou.myqcloud.com/blog/fz0rq.png)

0 commit comments

Comments
 (0)