Skip to content

Commit c0e35cd

Browse files
committed
✨feat: add 41、287
1 parent e8116c7 commit c0e35cd

File tree

3 files changed

+127
-42
lines changed

3 files changed

+127
-42
lines changed

Index/原地哈希.md

+2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
| 题目 | 题解 | 难度 | 推荐指数 |
22
| ------------------------------------------------------------ | ------------------------------------------------------------ | ---- | -------- |
3+
| [41. 缺失的第一个正数](https://leetcode.cn/problems/first-missing-positive/) | [LeetCode 题解链接](https://leetcode.cn/problems/first-missing-positive/solution/yan-ge-on-de-tong-pai-xu-si-lu-yi-ji-wei-wm8d/) | 困难 | 🤩🤩🤩🤩🤩 |
4+
| [287. 寻找重复数](https://leetcode.cn/problems/find-the-duplicate-number/) | [LeetCode 题解链接](https://leetcode.cn/problems/find-the-duplicate-number/solution/by-ac_oier-az8v/) | 中等 | 🤩🤩🤩🤩🤩 |
35
| [442. 数组中重复的数据](https://leetcode-cn.com/problems/find-all-duplicates-in-an-array/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/find-all-duplicates-in-an-array/solution/by-ac_oier-0m3c/) | 中等 | 🤩🤩🤩🤩🤩 |
46
| [448. 找到所有数组中消失的数字](https://leetcode-cn.com/problems/find-all-numbers-disappeared-in-an-array/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/find-all-numbers-disappeared-in-an-array/solution/li-yong-tong-pai-xu-de-si-lu-ni-huan-ke-e3t4w/) | 简单 | 🤩🤩🤩🤩🤩 |
57

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
### 题目描述
2+
3+
这是 LeetCode 上的 **[287. 寻找重复数](https://leetcode.cn/problems/find-the-duplicate-number/solution/by-ac_oier-az8v/)** ,难度为 **中等**
4+
5+
Tag : 「原地哈希」
6+
7+
8+
9+
给定一个包含 `n + 1` 个整数的数组 `nums`,其数字都在 $[1, n]$ 范围内(包括 $1$ 和 $n$),可知至少存在一个重复的整数。
10+
11+
假设 `nums` 只有 一个重复的整数 ,返回 这个重复的数 。
12+
13+
你设计的解决方案必须 不修改 数组 `nums` 且只用常量级 $O(1)$ 的额外空间。
14+
15+
示例 1:
16+
```
17+
输入:nums = [1,3,4,2,2]
18+
19+
输出:2
20+
```
21+
示例 2:
22+
```
23+
输入:nums = [3,1,3,4,2]
24+
25+
输出:3
26+
```
27+
28+
提示:
29+
* $1 <= n <= 10^5$
30+
* $nums.length = n + 1$
31+
* $1 <= nums[i] <= n$
32+
* `nums` 中 只有一个整数 出现 两次或多次 ,其余整数均只出现 一次
33+
34+
35+
进阶:
36+
* 如何证明 `nums` 中至少存在一个重复的数字?
37+
* 你可以设计一个线性级时间复杂度 $O(n)$ 的解决方案吗?
38+
39+
---
40+
41+
### 原地哈希
42+
43+
数组长度为 $n + 1$,同时给定的 $nums[i]$ 都在 $[1, n]$ 范围内,因此我们可以设定哈希规则为 $nums[idx] = idx + 1$,即数值 `x` 会放在下标 $x - 1$ 的位置。
44+
45+
如此一来,对于只出现一次的数值而言,必然能够顺利放在目标位置,而出现多次的数值必然会因为位置冲突而被找出。
46+
47+
Java 代码:
48+
```Java
49+
class Solution {
50+
public int findDuplicate(int[] nums) {
51+
for (int i = 0; i < nums.length; ) {
52+
int t = nums[i], idx = t - 1;
53+
if (nums[idx] == t) {
54+
if (idx != i) return t;
55+
i++;
56+
} else {
57+
swap(nums, idx, i);
58+
}
59+
}
60+
return -1;
61+
}
62+
void swap(int[] nums, int i, int j) {
63+
int c = nums[i];
64+
nums[i] = nums[j];
65+
nums[j] = c;
66+
}
67+
}
68+
```
69+
TypeScript 代码:
70+
```TypeScript
71+
function findDuplicate(nums: number[]): number {
72+
for (let i = 0; i < nums.length; ) {
73+
const t = nums[i], idx = t - 1
74+
if (nums[idx] == t) {
75+
if (idx != i) return t
76+
i++
77+
} else {
78+
swap(nums, i, idx)
79+
}
80+
}
81+
return -1
82+
}
83+
function swap(nums: number[], i: number, j: number): void {
84+
const c = nums[i]
85+
nums[i] = nums[j]
86+
nums[j] = c
87+
}
88+
```
89+
Python 代码:
90+
```Python
91+
class Solution:
92+
def findDuplicate(self, nums: List[int]) -> int:
93+
n, i = len(nums), 0
94+
while i < n:
95+
t, idx = nums[i], nums[i] - 1
96+
if nums[idx] == t:
97+
if idx != i:
98+
return t
99+
i += 1
100+
else:
101+
nums[i], nums[idx] = nums[idx], nums[i]
102+
return -1
103+
```
104+
* 时间复杂度:$O(n)$
105+
* 空间复杂度:$O(1)$
106+
107+
---
108+
109+
### 最后
110+
111+
这是我们「刷穿 LeetCode」系列文章的第 `No.287` 篇,系列开始于 2021/01/01,截止于起始日 LeetCode 上共有 1916 道题目,部分是有锁题,我们将先把所有不带锁的题目刷完。
112+
113+
在这个系列文章里面,除了讲解解题思路以外,还会尽可能给出最为简洁的代码。如果涉及通解还会相应的代码模板。
114+
115+
为了方便各位同学能够电脑上进行调试和提交代码,我建立了相关的仓库:https://github.com/SharingSource/LogicStack-LeetCode
116+
117+
在仓库地址里,你可以看到系列文章的题解链接、系列文章的相应代码、LeetCode 原题链接和其他优选题解。
118+

LeetCode/41-50/41. 缺失的第一个正数(困难).md

+7-42
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,13 @@
22

33
这是 LeetCode 上的 **[41. 缺失的第一个正数](https://leetcode-cn.com/problems/first-missing-positive/solution/yan-ge-on-de-tong-pai-xu-si-lu-yi-ji-wei-wm8d/)** ,难度为 **困难**
44

5-
Tag : 「桶排序」
5+
Tag : 「桶排序」、「原地哈希」
66

77

88

9-
给你一个未排序的整数数组 nums ,请你找出其中没有出现的最小的正整数。
9+
给你一个未排序的整数数组 `nums` ,请你找出其中没有出现的最小的正整数。
1010

11-
 **进阶**:你可以实现时间复杂度为 O(n) 并且只使用常数级别额外空间的解决方案吗?
12-
13-
 
11+
 **进阶**:你可以实现时间复杂度为 $O(n)$ 并且只使用常数级别额外空间的解决方案吗? 
1412

1513
示例 1:
1614
```
@@ -32,12 +30,12 @@ Tag : 「桶排序」
3230
```
3331

3432
提示:
35-
* 0 <= nums.length <= 300
36-
* -$2^{31}$ <= nums[i] <= $2^{31}$ - 1
33+
* $0 <= nums.length <= 300$
34+
* $-2^{31} <= nums[i] <= 2^{31} - 1$
3735

3836
---
3937

40-
### 桶排序
38+
### 桶排序(原地哈希)
4139

4240
令数组长度为 `n`,那么答案必然在 `[1, n + 1]` 范围内。
4341

@@ -80,42 +78,9 @@ class Solution {
8078

8179
---
8280

83-
### 实战技巧
84-
85-
还记得最早我在 [4. 寻找两个正序数组的中位数](https://mp.weixin.qq.com/s/BUjjFgsSEz5ZpT7_qe24Ww) 跟你说过,对于一些从文字上限制我们的题目,我们应该如何分析能否采用别的做法来 AC。
86-
87-
这对于比赛和机试,这种要求我们尽快 AC 的场景来说,尤为重要。
88-
89-
总的来说,你可以根据**直观解法的时空复杂度****文字限制的时空复杂度****数据范围**等几个方面来判断。
90-
91-
对于本题而言,我们可以很容易想到先排序,再遍历的做法:
92-
93-
排序的复杂度为 $O(n\log{n})$;找答案的过程需要枚举 `[1, n]`,然后通过「二分」找当前的枚举值是否在排序数据中,复杂度为 $O(n\log{n})$。因此整体复杂度为 $O(n\log{n})$。
94-
95-
而文字要求我们使用 $O(n)$ 复杂度的解法。这时候我们基本上可以不看数据范围就可以确定 $O(n\log{n})$ 能做。
96-
97-
因为 $O(n\log{n})$ 和 $O(n)$ 并没有差多少,哪怕数据范围出到极限 $10^7$。$log{10^7}$ = 23,数值非常小,$O(n\log{n})$ 可以等效看做一个常数计算为 23 的 $O(n)$ 解法。何况本题的数据范围只有 300,可以说怎么做都行。
98-
99-
$O(n\log{n})$ 解法代码:
100-
```java
101-
class Solution {
102-
public int firstMissingPositive(int[] nums) {
103-
Arrays.sort(nums);
104-
int n = nums.length;
105-
for (int i = 1; i <= n; i++) {
106-
if (Arrays.binarySearch(nums, i) < 0) return i;
107-
}
108-
return n + 1;
109-
}
110-
}
111-
```
112-
你会发现,在 LeetCode 上 $O(n\log{n})$ 解法和 $O(n)$ 解法的执行用时没有差别。
113-
114-
---
115-
11681
### 最后
11782

118-
这是我们「刷穿 LeetCode」系列文章的第 `No.` 篇,系列开始于 2021/01/01,截止于起始日 LeetCode 上共有 1916 道题目,部分是有锁题,我们将先把所有不带锁的题目刷完。
83+
这是我们「刷穿 LeetCode」系列文章的第 `No.41` 篇,系列开始于 2021/01/01,截止于起始日 LeetCode 上共有 1916 道题目,部分是有锁题,我们将先把所有不带锁的题目刷完。
11984

12085
在这个系列文章里面,除了讲解解题思路以外,还会尽可能给出最为简洁的代码。如果涉及通解还会相应的代码模板。
12186

0 commit comments

Comments
 (0)