Skip to content

Commit afdc693

Browse files
author
Kyle Liu
committed
add some doc
1 parent e09034c commit afdc693

File tree

2 files changed

+269
-0
lines changed

2 files changed

+269
-0
lines changed

lcof/of003/README.md

Lines changed: 203 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,203 @@
1+
---
2+
description: 剑指 Offer 03. 数组中重复的数字
3+
---
4+
5+
# OF3.数组中重复的数字
6+
7+
## 题目描述
8+
9+
[题目地址](https://leetcode-cn.com/problems/shu-zu-zhong-zhong-fu-de-shu-zi-lcof/)
10+
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
21+
```
22+
23+
### **限制:**
24+
25+
```go
26+
2 <= n <= 100000
27+
```
28+
29+
## 题解
30+
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+
### 思路2:**原地交换**
110+
111+
#### 算法流程
112+
113+
1. 遍历数组 numsnums ,设索引初始值为 i = 0i=0 :
114+
1. 若 nums\[i\] = inums\[i\]=i : 说明此数字已在对应索引位置,无需交换,因此跳过
115+
2. 若 nums\[nums\[i\]\] = nums\[i\]nums\[nums\[i\]\]=nums\[i\] : 代表索引 nums\[i\]nums\[i\] 处和索引 ii 处的元素值都为 nums\[i\]nums\[i\] ,即找到一组重复值,返回此值 nums\[i\]nums\[i\]
116+
3. 否则: 交换索引为 ii 和 nums\[i\]nums\[i\] 的元素值,将此数字交换至对应索引位置
117+
2. 若遍历完毕尚未返回,则返回 -1
118+
119+
#### 复杂度分析
120+
121+
* **时间复杂度**$$O(N)$$****遍历数组使用 $$O(N)$$ ,每轮遍历的判断和交换操作使用 $$O(N)$$
122+
* **空间复杂度**$$O(1)$$**** 使用常数复杂度的额外空间。
123+
124+
{% tabs %}
125+
{% tab title="Go" %}
126+
```go
127+
func findRepeatNumber3(nums []int) int {
128+
for idx, val := range nums {
129+
if idx == val {
130+
continue
131+
}
132+
if nums[val] == val {
133+
return val
134+
}
135+
nums[val], nums[idx] = nums[idx], nums[val]
136+
}
137+
return 0
138+
}
139+
```
140+
{% endtab %}
141+
142+
{% tab title="Python" %}
143+
```python
144+
class Solution:
145+
def findRepeatNumber(self, nums: [int]) -> int:
146+
i = 0
147+
while i < len(nums):
148+
if nums[i] == i:
149+
i += 1
150+
continue
151+
if nums[nums[i]] == nums[i]: return nums[i]
152+
nums[nums[i]], nums[i] = nums[i], nums[nums[i]]
153+
return -1
154+
```
155+
{% endtab %}
156+
157+
{% tab title="Java" %}
158+
```java
159+
class Solution {
160+
public int findRepeatNumber(int[] nums) {
161+
int i = 0;
162+
while(i < nums.length) {
163+
if(nums[i] == i) {
164+
i++;
165+
continue;
166+
}
167+
if(nums[nums[i]] == nums[i]) return nums[i];
168+
int tmp = nums[i];
169+
nums[i] = nums[tmp];
170+
nums[tmp] = tmp;
171+
}
172+
return -1;
173+
}
174+
}
175+
```
176+
{% endtab %}
177+
178+
{% tab title="C++" %}
179+
```cpp
180+
class Solution {
181+
public:
182+
int findRepeatNumber(vector<int>& nums) {
183+
int i = 0;
184+
while(i < nums.size()) {
185+
if(nums[i] == i) {
186+
i++;
187+
continue;
188+
}
189+
if(nums[nums[i]] == nums[i])
190+
return nums[i];
191+
swap(nums[i],nums[nums[i]]);
192+
}
193+
return -1;
194+
}
195+
};
196+
```
197+
{% endtab %}
198+
{% endtabs %}
199+
200+
## 总结
201+
202+
如果你同我一样热爱数据结构、算法、LeetCode,可以关注我 GitHub 上的 算法 题解:[awesome-golang-algorithm](https://github.com/kylesliu/awesome-golang-algorithm)
203+

lcof/of037/README.md

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
---
2+
description: 剑指 Offer 37. 序列化二叉树
3+
---
4+
5+
# OF37.序列化二叉树
6+
7+
## 题目描述
8+
9+
[题目地址](https://leetcode-cn.com/problems/xu-lie-hua-er-cha-shu-lcof/)
10+
11+
序列化是将一个数据结构或者对象转换为连续的比特位的操作,进而可以将转换后的数据存储在一个文件或者内存中,同时也可以通过网络传输到另一个计算机环境,采取相反方式重构得到原数据。
12+
13+
请设计一个算法来实现二叉树的序列化与反序列化。这里不限定你的序列 / 反序列化算法执行逻辑,你只需要保证一个二叉树可以被序列化为一个字符串并且将这个字符串反序列化为原始的树结构。
14+
15+
16+
17+
### **示例 1:**
18+
19+
```go
20+
你可以将以下二叉树:
21+
22+
1
23+
/ \
24+
2 3
25+
/ \
26+
4 5
27+
28+
序列化为 "[1,2,3,null,null,4,5]"
29+
```
30+
31+
## 题解
32+
33+
### 思路1 :
34+
35+
**算法流程:**
36+
37+
1.
38+
**复杂度分析:**
39+
40+
* **时间复杂度**$$O(N)$$****\)
41+
* **空间复杂度**$$O(N)$$****
42+
43+
#### 代码
44+
45+
{% tabs %}
46+
{% tab title="Go" %}
47+
```go
48+
func findRepeatNumber2(nums []int) int {
49+
mapTmp := make(map[int]bool)
50+
for _, val := range nums {
51+
if mapTmp[val] {
52+
return val
53+
} else {
54+
mapTmp[val] = true
55+
}
56+
}
57+
return 0
58+
}
59+
```
60+
{% endtab %}
61+
{% endtabs %}
62+
63+
## 总结
64+
65+
如果你同我一样热爱数据结构、算法、LeetCode,可以关注我 GitHub 上的 算法 题解:[awesome-golang-algorithm](https://github.com/kylesliu/awesome-golang-algorithm)
66+

0 commit comments

Comments
 (0)