Skip to content

Commit a32f227

Browse files
committed
feat: add solutions to lcof problem: No.03
1 parent d92d3b4 commit a32f227

File tree

8 files changed

+235
-148
lines changed

8 files changed

+235
-148
lines changed

lcof/面试题03. 数组中重复的数字/README.md

Lines changed: 184 additions & 89 deletions
Original file line numberDiff line numberDiff line change
@@ -22,16 +22,23 @@
2222

2323
## 解法
2424

25-
三种方式
25+
**方法一:排序**
2626

27-
- 排序
28-
- 先排序,将相同的数字聚集到一起。
29-
- 再遍历,当位于 `i``i + 1` 的数字相等时,返回该数字。
30-
- 哈希表
31-
- 记录数字在数组中的数量,当数量为 2 时,返回即可。
32-
- 原地交换
33-
- 0 ~ n-1 范围内的数,分别还原到对应的位置上,如:数字 2 交换到下标为 2 的位置。
34-
- 若交换过程中发现重复,则直接返回。
27+
我们可以先对数组 `nums` 进行排序,然后遍历排序后的数组,判断相邻的两个元素是否相等,如果相等,即找到了一个重复的数字,返回该数字即可。
28+
29+
时间复杂度 $O(n \times \log n)$,空间复杂度 $O(\log n)$。其中 $n$ 是数组 `nums` 的长度。
30+
31+
**方法二:哈希表**
32+
33+
我们可以使用哈希表来解决这个问题,遍历数组 `nums`,对于遍历到的每个元素,判断哈希表中是否存在该元素,如果哈希表中存在该元素,即找到了一个重复的数字,返回该数字即可;如果哈希表中不存在该元素,将该元素加入哈希表中。继续遍历,直到找到一个重复的数字。
34+
35+
时间复杂度 $O(n)$,空间复杂度 $O(n)$。其中 $n$ 是数组 `nums` 的长度。
36+
37+
**方法三:原地交换**
38+
39+
我们可以遍历数组 `nums`,对于遍历到的每个元素 `nums[i]`,判断 `nums[i]` 是否等于 `i`,如果是,则继续遍历下一个元素;如果不是,则将 `nums[i]``nums[nums[i]]` 进行交换,交换之后,`nums[i]` 的值和下标都发生了改变,如果 `nums[i]``nums[nums[i]]` 相等,即找到了一个重复的数字,返回该数字即可;如果 `nums[i]``nums[nums[i]]` 不相等,继续遍历,直到找到一个重复的数字。
40+
41+
时间复杂度 $O(n)$,空间复杂度 $O(1)$。其中 $n$ 是数组 `nums` 的长度。
3542

3643
<!-- tabs:start -->
3744

@@ -40,113 +47,181 @@
4047
```python
4148
class Solution:
4249
def findRepeatNumber(self, nums: List[int]) -> int:
43-
for i, num in enumerate(nums):
44-
while i != num:
45-
if num == nums[num]:
46-
return num
47-
nums[i], nums[num] = nums[num], nums[i]
48-
num = nums[i]
49-
return -1
50+
for a, b in pairwise(sorted(nums)):
51+
if a == b:
52+
return a
53+
```
54+
55+
```python
56+
class Solution:
57+
def findRepeatNumber(self, nums: List[int]) -> int:
58+
vis = set()
59+
for v in nums:
60+
if v in vis:
61+
return v
62+
vis.add(v)
63+
```
64+
65+
```python
66+
class Solution:
67+
def findRepeatNumber(self, nums: List[int]) -> int:
68+
for i, v in enumerate(nums):
69+
while v != i:
70+
if nums[v] == v:
71+
return v
72+
nums[i], nums[v] = nums[v], nums[i]
73+
v = nums[i]
5074
```
5175

5276
### **Java**
5377

5478
```java
5579
class Solution {
5680
public int findRepeatNumber(int[] nums) {
57-
for (int i = 0, n = nums.length; i < n; ++i) {
58-
while (nums[i] != i) {
59-
if (nums[i] == nums[nums[i]]) return nums[i];
60-
swap(nums, i, nums[i]);
81+
Arrays.sort(nums);
82+
for (int i = 0; ; ++i) {
83+
if (nums[i] == nums[i + 1]) {
84+
return nums[i];
6185
}
6286
}
63-
return -1;
6487
}
88+
}
89+
```
6590

66-
private void swap(int[] nums, int i, int j) {
67-
int t = nums[i];
68-
nums[i] = nums[j];
69-
nums[j] = t;
91+
```java
92+
class Solution {
93+
public int findRepeatNumber(int[] nums) {
94+
Set<Integer> vis = new HashSet<>();
95+
for (int i = 0; ; ++i) {
96+
if (!vis.add(nums[i])) {
97+
return nums[i];
98+
}
99+
}
70100
}
71101
}
72102
```
73103

74-
### **Kotlin**
75-
76-
```kotlin
104+
```java
77105
class Solution {
78-
fun findRepeatNumber(nums: IntArray): Int {
79-
for (i in nums.indices) {
80-
while (i != nums[i]) {
81-
if (nums[i] == nums[nums[i]]) {
82-
return nums[i];
106+
public int findRepeatNumber(int[] nums) {
107+
for (int i = 0; ; ++i) {
108+
while (nums[i] != i) {
109+
int j = nums[i];
110+
if (nums[j] == j) {
111+
return j;
83112
}
84-
swap(nums, i, nums[i]);
113+
int t = nums[i];
114+
nums[i] = nums[j];
115+
nums[j] = t;
85116
}
86117
}
87-
return -1;
88-
}
89-
90-
fun swap(nums: IntArray, i: Int, j: Int) {
91-
var t = nums[i];
92-
nums[i] = nums[j];
93-
nums[j] = t;
94118
}
95119
}
96120
```
97121

98-
### **JavaScript**
122+
### **C++**
99123

100-
```js
101-
/**
102-
* @param {number[]} nums
103-
* @return {number}
104-
*/
105-
var findRepeatNumber = function (nums) {
106-
let m = {};
107-
for (let num of nums) {
108-
if (m[num]) return num;
109-
m[num] = 1;
124+
```cpp
125+
class Solution {
126+
public:
127+
int findRepeatNumber(vector<int>& nums) {
128+
sort(nums.begin(), nums.end());
129+
for (int i = 0; ; ++i) {
130+
if (nums[i] == nums[i + 1]) {
131+
return nums[i];
132+
}
133+
}
110134
}
111135
};
112136
```
113137
114-
### **Go**
115-
116-
```go
117-
func findRepeatNumber(nums []int) int {
118-
for i := 0; i < len(nums); i++ {
119-
for nums[i] != i {
120-
if nums[i] == nums[nums[i]] {
121-
return nums[i]
138+
```cpp
139+
class Solution {
140+
public:
141+
int findRepeatNumber(vector<int>& nums) {
142+
unordered_set<int> vis;
143+
for (int i = 0; ; ++i) {
144+
if (vis.count(nums[i])) {
145+
return nums[i];
122146
}
123-
nums[i], nums[nums[i]] = nums[nums[i]], nums[i]
147+
vis.insert(nums[i]);
124148
}
125149
}
126-
return -1
127-
}
150+
};
128151
```
129152

130-
### **C++**
131-
132153
```cpp
133154
class Solution {
134155
public:
135156
int findRepeatNumber(vector<int>& nums) {
136-
int len = nums.size();
137-
for (int i = 0; i < len; i++) {
138-
while (i != nums[i]) {
139-
// 这一位的值,不等于这一位的数字
140-
if (nums[i] == nums[nums[i]]) {
141-
// 如果在交换的过程中,发现了相等的数字,直接返回
142-
return nums[i];
157+
for (int i = 0; ; ++i) {
158+
while (nums[i] != i) {
159+
int j = nums[i];
160+
if (nums[j] == j) {
161+
return j;
143162
}
144-
145-
swap(nums[i], nums[nums[i]]);
163+
swap(nums[i], nums[j]);
146164
}
147165
}
166+
}
167+
};
168+
```
169+
170+
### **Go**
171+
172+
```go
173+
func findRepeatNumber(nums []int) int {
174+
sort.Ints(nums)
175+
for i := 0; ; i++ {
176+
if nums[i] == nums[i+1] {
177+
return nums[i]
178+
}
179+
}
180+
}
181+
```
182+
183+
```go
184+
func findRepeatNumber(nums []int) int {
185+
vis := map[int]bool{}
186+
for i := 0; ; i++ {
187+
if vis[nums[i]] {
188+
return nums[i]
189+
}
190+
vis[nums[i]] = true
191+
}
192+
}
193+
```
194+
195+
```go
196+
func findRepeatNumber(nums []int) int {
197+
for i := 0; ; i++ {
198+
for nums[i] != i {
199+
j := nums[i]
200+
if nums[j] == j {
201+
return j
202+
}
203+
nums[i], nums[j] = nums[j], nums[i]
204+
}
205+
}
206+
}
207+
```
208+
209+
### **JavaScript**
148210

149-
return 0;
211+
```js
212+
/**
213+
* @param {number[]} nums
214+
* @return {number}
215+
*/
216+
var findRepeatNumber = function (nums) {
217+
for (let i = 0; ; ++i) {
218+
while (nums[i] != i) {
219+
const j = nums[i];
220+
if (nums[j] == j) {
221+
return j;
222+
}
223+
[nums[i], nums[j]] = [nums[j], nums[i]];
224+
}
150225
}
151226
};
152227
```
@@ -155,18 +230,15 @@ public:
155230

156231
```ts
157232
function findRepeatNumber(nums: number[]): number {
158-
let n: number = nums.length;
159-
for (let i: number = 0; i < n; i++) {
233+
for (let i = 0; ; ++i) {
160234
while (nums[i] != i) {
161-
if (nums[i] == nums[nums[i]]) return nums[i];
162-
swap(nums, i, nums[i]);
235+
const j = nums[i];
236+
if (nums[j] == j) {
237+
return j;
238+
}
239+
[nums[i], nums[j]] = [nums[j], nums[i]];
163240
}
164241
}
165-
return -1;
166-
}
167-
168-
function swap(nums: number[], i: number, j: number): void {
169-
[nums[i], nums[j]] = [nums[j], nums[i]];
170242
}
171243
```
172244

@@ -194,19 +266,42 @@ impl Solution {
194266
```cs
195267
public class Solution {
196268
public int FindRepeatNumber(int[] nums) {
197-
int temp;
198-
for (int i = 0; i < nums.Length; i++) {
269+
for (int i = 0; ; ++i) {
270+
while (nums[i] != i) {
271+
int j = nums[i];
272+
if (nums[j] == j) {
273+
return j;
274+
}
275+
int t = nums[i];
276+
nums[i] = nums[j];
277+
nums[j] = t;
278+
}
279+
}
280+
}
281+
}
282+
```
283+
284+
### **Kotlin**
285+
286+
```kotlin
287+
class Solution {
288+
fun findRepeatNumber(nums: IntArray): Int {
289+
for (i in nums.indices) {
199290
while (i != nums[i]) {
200291
if (nums[i] == nums[nums[i]]) {
201292
return nums[i];
202293
}
203-
temp = nums[i];
204-
nums[i] = nums[temp];
205-
nums[temp] = temp;
294+
swap(nums, i, nums[i]);
206295
}
207296
}
208297
return -1;
209298
}
299+
300+
fun swap(nums: IntArray, i: Int, j: Int) {
301+
var t = nums[i];
302+
nums[i] = nums[j];
303+
nums[j] = t;
304+
}
210305
}
211306
```
212307

Lines changed: 6 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,14 @@
11
class Solution {
22
public:
33
int findRepeatNumber(vector<int>& nums) {
4-
int len = nums.size();
5-
for (int i = 0; i < len; i++) {
6-
while (i != nums[i]) {
7-
// 这一位的值,不等于这一位的数字
8-
if (nums[i] == nums[nums[i]]) {
9-
// 如果在交换的过程中,发现了相等的数字,直接返回
10-
return nums[i];
4+
for (int i = 0; ; ++i) {
5+
while (nums[i] != i) {
6+
int j = nums[i];
7+
if (nums[j] == j) {
8+
return j;
119
}
12-
13-
swap(nums[i], nums[nums[i]]);
10+
swap(nums[i], nums[j]);
1411
}
1512
}
16-
17-
return 0;
1813
}
1914
};

0 commit comments

Comments
 (0)