Skip to content

Commit 47a60f9

Browse files
author
Kyle Liu
committed
add a note for offer
1 parent 4969e08 commit 47a60f9

File tree

1 file changed

+189
-17
lines changed

1 file changed

+189
-17
lines changed

lcof/of003/README.md

Lines changed: 189 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,204 @@
1-
# [OF0.Template Title][title]
2-
3-
> [!WARNING|style:flat]
4-
> This problem is temporarily not PR, please submit [Create Pull Request PR](https://github.com/kylesliu/awesome-golang-algorithm)
1+
---
2+
description: 剑指 Offer 03. 数组中重复的数字
3+
---
54

5+
# OF3.数组中重复的数字
66

77
## 题目描述
8-
....
98

10-
**范例 :**
9+
[题目地址](https://leetcode-cn.com/problems/shu-zu-zhong-zhong-fu-de-shu-zi-lcof/)
1110

11+
找出数组中重复的数字。
12+
13+
在一个长度为 n 的数组 _`nums`_ 里的所有数字都在 0~n-1 的范围内。数组中某些数字是重复的,但不知道有几个数字重复了,也不知道每个数字重复了几次。请找出数组中任意一个重复的数字。
14+
15+
### **示例 1:**
16+
17+
```go
18+
输入:
19+
[2, 3, 1, 0, 2, 5, 3]
20+
输出:23
1221
```
13-
Input: n=1
14-
Output: 1
15-
```
1622

17-
## 题意
18-
> ...
23+
### **限制:**
24+
25+
```go
26+
2 <= n <= 100000
27+
```
1928

2029
## 题解
2130

22-
### 思路1
23-
> ...
31+
### 思路1 : **哈希表 / Set**
32+
33+
**算法流程:**
34+
35+
1. 初始化: 新建 HashSet ,记为 dicdic
36+
2. 遍历数组 numsnums 中的每个数字 numnum
37+
1. 当 num 在 dic 中,说明重复,直接返回 num
38+
2. 将 numnum 添加至 dicdic 中
39+
3. 返回 -1−1 。本题中一定有重复数字,因此这里返回多少都可以
40+
41+
**复杂度分析:**
42+
43+
* **时间复杂度**$$O(N)$$****遍历数组使用 O\(N\) ,HashSet 添加与查找元素皆为 O\(1\)O\(1\)
44+
* **空间复杂度**$$O(N)$$**** HashSet 占用 O\(N\) 大小的额外空间
45+
46+
#### 代码
47+
48+
{% tabs %}
49+
{% tab title="Go" %}
50+
```go
51+
func findRepeatNumber2(nums []int) int {
52+
mapTmp := make(map[int]bool)
53+
for _, val := range nums {
54+
if mapTmp[val] {
55+
return val
56+
} else {
57+
mapTmp[val] = true
58+
}
59+
}
60+
return 0
61+
}
62+
```
63+
{% endtab %}
64+
65+
{% tab title="Python" %}
66+
```python
67+
class Solution:
68+
def findRepeatNumber(self, nums: [int]) -> int:
69+
dic = set()
70+
for num in nums:
71+
if num in dic: return num
72+
dic.add(num)
73+
return -1
74+
```
75+
{% endtab %}
76+
77+
{% tab title="C++" %}
78+
```cpp
79+
class Solution {
80+
public:
81+
int findRepeatNumber(vector<int>& nums) {
82+
unordered_map<int, bool> map;
83+
for(int num : nums) {
84+
if(map[num]) return num;
85+
map[num] = true;
86+
}
87+
return -1;
88+
}
89+
};
90+
```
91+
{% endtab %}
92+
93+
{% tab title="Java" %}
94+
```java
95+
class Solution {
96+
public int findRepeatNumber(int[] nums) {
97+
Set<Integer> dic = new HashSet<>();
98+
for(int num : nums) {
99+
if(dic.contains(num)) return num;
100+
dic.add(num);
101+
}
102+
return -1;
103+
}
104+
}
105+
```
106+
{% endtab %}
107+
{% endtabs %}
108+
109+
110+
111+
### 思路2:**原地交换**
112+
113+
#### 算法流程
114+
115+
1. 遍历数组 numsnums ,设索引初始值为 i = 0i=0 :
116+
1. 若 nums\[i\] = inums\[i\]=i : 说明此数字已在对应索引位置,无需交换,因此跳过
117+
2. 若 nums\[nums\[i\]\] = nums\[i\]nums\[nums\[i\]\]=nums\[i\] : 代表索引 nums\[i\]nums\[i\] 处和索引 ii 处的元素值都为 nums\[i\]nums\[i\] ,即找到一组重复值,返回此值 nums\[i\]nums\[i\]
118+
3. 否则: 交换索引为 ii 和 nums\[i\]nums\[i\] 的元素值,将此数字交换至对应索引位置
119+
2. 若遍历完毕尚未返回,则返回 -1
120+
121+
#### 复杂度分析
122+
123+
* **时间复杂度**$$O(N)$$****遍历数组使用 $$O(N)$$ ,每轮遍历的判断和交换操作使用 $$O(N)$$
124+
* **空间复杂度**$$O(1)$$**** 使用常数复杂度的额外空间。
125+
126+
{% tabs %}
127+
{% tab title="Go" %}
24128
```go
129+
func findRepeatNumber3(nums []int) int {
130+
for idx, val := range nums {
131+
if idx == val {
132+
continue
133+
}
134+
if nums[val] == val {
135+
return val
136+
}
137+
nums[val], nums[idx] = nums[idx], nums[val]
138+
}
139+
return 0
140+
}
25141
```
142+
{% endtab %}
26143

27-
## 结语
144+
{% tab title="Python" %}
145+
```python
146+
class Solution:
147+
def findRepeatNumber(self, nums: [int]) -> int:
148+
i = 0
149+
while i < len(nums):
150+
if nums[i] == i:
151+
i += 1
152+
continue
153+
if nums[nums[i]] == nums[i]: return nums[i]
154+
nums[nums[i]], nums[i] = nums[i], nums[nums[i]]
155+
return -1
156+
```
157+
{% endtab %}
158+
159+
{% tab title="Java" %}
160+
```java
161+
class Solution {
162+
public int findRepeatNumber(int[] nums) {
163+
int i = 0;
164+
while(i < nums.length) {
165+
if(nums[i] == i) {
166+
i++;
167+
continue;
168+
}
169+
if(nums[nums[i]] == nums[i]) return nums[i];
170+
int tmp = nums[i];
171+
nums[i] = nums[tmp];
172+
nums[tmp] = tmp;
173+
}
174+
return -1;
175+
}
176+
}
177+
```
178+
{% endtab %}
179+
180+
{% tab title="C++" %}
181+
```cpp
182+
class Solution {
183+
public:
184+
int findRepeatNumber(vector<int>& nums) {
185+
int i = 0;
186+
while(i < nums.size()) {
187+
if(nums[i] == i) {
188+
i++;
189+
continue;
190+
}
191+
if(nums[nums[i]] == nums[i])
192+
return nums[i];
193+
swap(nums[i],nums[nums[i]]);
194+
}
195+
return -1;
196+
}
197+
};
198+
```
199+
{% endtab %}
200+
{% endtabs %}
28201
29-
如果你同我一样热爱数据结构、算法、LeetCode,可以关注我 GitHub 上的 LeetCode 题解:[awesome-golang-algorithm][me]
202+
## 总结
30203
31-
[title]: https://www.nowcoder.com/practice/c6c7742f5ba7442aada113136ddea0c3/
32-
[me]: https://github.com/kylesliu/awesome-golang-algorithm
204+
如果你同我一样热爱数据结构、算法、LeetCode,可以关注我 GitHub 上的 算法 题解:[awesome-golang-algorithm](https://github.com/kylesliu/awesome-golang-algorithm)

0 commit comments

Comments
 (0)