Skip to content

Commit 9edb1a4

Browse files
authored
feat: add solutions to lcci problem: No.08.06 (#1392)
No.08.06.Hanota
1 parent 74a8576 commit 9edb1a4

File tree

7 files changed

+554
-0
lines changed

7 files changed

+554
-0
lines changed

lcci/08.06.Hanota/README.md

+236
Original file line numberDiff line numberDiff line change
@@ -29,22 +29,258 @@
2929

3030
<!-- 这里可写通用的实现逻辑 -->
3131

32+
**方法一:递归**
33+
34+
我们设计一个函数 $dfs(n, a, b, c)$,表示将 $n$ 个盘子从 $a$ 移动到 $c$,其中 $b$ 为辅助柱子。
35+
36+
我们先将 $n - 1$ 个盘子从 $a$ 移动到 $b$,然后将第 $n$ 个盘子从 $a$ 移动到 $c$,最后将 $n - 1$ 个盘子从 $b$ 移动到 $c$。
37+
38+
时间复杂度 $O(2^n)$,空间复杂度 $O(n)$。其中 $n$ 是盘子的数目。
39+
40+
**方法二:迭代(栈)**
41+
42+
我们可以用栈来模拟递归的过程。
43+
44+
我们定义一个结构体 $Task$,表示一个任务,其中 $n$ 表示盘子的数目,而 $a$, $b$, $c$ 表示三根柱子。
45+
46+
我们将初始任务 $Task(len(A), A, B, C)$ 压入栈中,然后不断取出栈顶任务进行处理,直到栈为空。
47+
48+
如果 $n = 1$,那么我们直接将盘子从 $a$ 移动到 $c$。
49+
50+
否则,我们将三个子任务压入栈中,分别是:
51+
52+
1. 将 $n - 1$ 个盘子从 $b$ 借助 $a$ 移动到 $c$;
53+
2. 将第 $n$ 个盘子从 $a$ 移动到 $c$;
54+
3. 将 $n - 1$ 个盘子从 $a$ 借助 $c$ 移动到 $b$。
55+
56+
时间复杂度 $O(2^n)$,空间复杂度 $O(n)$。其中 $n$ 是盘子的数目。
57+
3258
<!-- tabs:start -->
3359

3460
### **Python3**
3561

3662
<!-- 这里可写当前语言的特殊实现逻辑 -->
3763

3864
```python
65+
class Solution:
66+
def hanota(self, A: List[int], B: List[int], C: List[int]) -> None:
67+
def dfs(n, a, b, c):
68+
if n == 1:
69+
c.append(a.pop())
70+
return
71+
dfs(n - 1, a, c, b)
72+
c.append(a.pop())
73+
dfs(n - 1, b, a, c)
3974

75+
dfs(len(A), A, B, C)
76+
```
77+
78+
```python
79+
class Solution:
80+
def hanota(self, A: List[int], B: List[int], C: List[int]) -> None:
81+
stk = [(len(A), A, B, C)]
82+
while stk:
83+
n, a, b, c = stk.pop()
84+
if n == 1:
85+
c.append(a.pop())
86+
else:
87+
stk.append((n - 1, b, a, c))
88+
stk.append((1, a, b, c))
89+
stk.append((n - 1, a, c, b))
4090
```
4191

4292
### **Java**
4393

4494
<!-- 这里可写当前语言的特殊实现逻辑 -->
4595

4696
```java
97+
class Solution {
98+
public void hanota(List<Integer> A, List<Integer> B, List<Integer> C) {
99+
dfs(A.size(), A, B, C);
100+
}
101+
102+
private void dfs(int n, List<Integer> a, List<Integer> b, List<Integer> c) {
103+
if (n == 1) {
104+
c.add(a.remove(a.size() - 1));
105+
return;
106+
}
107+
dfs(n - 1, a, c, b);
108+
c.add(a.remove(a.size() - 1));
109+
dfs(n - 1, b, a, c);
110+
}
111+
}
112+
```
113+
114+
```java
115+
class Solution {
116+
public void hanota(List<Integer> A, List<Integer> B, List<Integer> C) {
117+
Deque<Task> stk = new ArrayDeque<>();
118+
stk.push(new Task(A.size(), A, B, C));
119+
while (stk.size() > 0) {
120+
Task task = stk.pop();
121+
int n = task.n;
122+
List<Integer> a = task.a;
123+
List<Integer> b = task.b;
124+
List<Integer> c = task.c;
125+
if (n == 1) {
126+
c.add(a.remove(a.size() - 1));
127+
} else {
128+
stk.push(new Task(n - 1, b, a, c));
129+
stk.push(new Task(1, a, b, c));
130+
stk.push(new Task(n - 1, a, c, b));
131+
}
132+
}
133+
}
134+
}
135+
136+
class Task {
137+
int n;
138+
List<Integer> a;
139+
List<Integer> b;
140+
List<Integer> c;
141+
142+
public Task(int n, List<Integer> a, List<Integer> b, List<Integer> c) {
143+
this.n = n;
144+
this.a = a;
145+
this.b = b;
146+
this.c = c;
147+
}
148+
}
149+
```
150+
151+
### **C++**
152+
153+
```cpp
154+
class Solution {
155+
public:
156+
void hanota(vector<int>& A, vector<int>& B, vector<int>& C) {
157+
function<void(int, vector<int>&, vector<int>&, vector<int>&)> dfs = [&](int n, vector<int>& a, vector<int>& b, vector<int>& c) {
158+
if (n == 1) {
159+
c.push_back(a.back());
160+
a.pop_back();
161+
return;
162+
}
163+
dfs(n - 1, a, c, b);
164+
c.push_back(a.back());
165+
a.pop_back();
166+
dfs(n - 1, b, a, c);
167+
};
168+
dfs(A.size(), A, B, C);
169+
}
170+
};
171+
```
172+
173+
```cpp
174+
struct Task {
175+
int n;
176+
vector<int>* a;
177+
vector<int>* b;
178+
vector<int>* c;
179+
};
180+
181+
class Solution {
182+
public:
183+
void hanota(vector<int>& A, vector<int>& B, vector<int>& C) {
184+
stack<Task> stk;
185+
stk.push({(int) A.size(), &A, &B, &C});
186+
while (!stk.empty()) {
187+
Task task = stk.top();
188+
stk.pop();
189+
if (task.n == 1) {
190+
task.c->push_back(task.a->back());
191+
task.a->pop_back();
192+
} else {
193+
stk.push({task.n - 1, task.b, task.a, task.c});
194+
stk.push({1, task.a, task.b, task.c});
195+
stk.push({task.n - 1, task.a, task.c, task.b});
196+
}
197+
}
198+
}
199+
};
200+
```
201+
202+
### **Go**
203+
204+
```go
205+
func hanota(A []int, B []int, C []int) []int {
206+
var dfs func(n int, a, b, c *[]int)
207+
dfs = func(n int, a, b, c *[]int) {
208+
if n == 1 {
209+
*c = append(*c, (*a)[len(*a)-1])
210+
*a = (*a)[:len(*a)-1]
211+
return
212+
}
213+
dfs(n-1, a, c, b)
214+
*c = append(*c, (*a)[len(*a)-1])
215+
*a = (*a)[:len(*a)-1]
216+
dfs(n-1, b, a, c)
217+
}
218+
dfs(len(A), &A, &B, &C)
219+
return C
220+
}
221+
```
222+
223+
```go
224+
func hanota(A []int, B []int, C []int) []int {
225+
stk := []Task{{len(A), &A, &B, &C}}
226+
for len(stk) > 0 {
227+
task := stk[len(stk)-1]
228+
stk = stk[:len(stk)-1]
229+
if task.n == 1 {
230+
*task.c = append(*task.c, (*task.a)[len(*task.a)-1])
231+
*task.a = (*task.a)[:len(*task.a)-1]
232+
} else {
233+
stk = append(stk, Task{task.n - 1, task.b, task.a, task.c})
234+
stk = append(stk, Task{1, task.a, task.b, task.c})
235+
stk = append(stk, Task{task.n - 1, task.a, task.c, task.b})
236+
}
237+
}
238+
return C
239+
}
240+
241+
type Task struct {
242+
n int
243+
a, b, c *[]int
244+
}
245+
```
246+
247+
### **TypeScript**
248+
249+
```ts
250+
/**
251+
Do not return anything, modify C in-place instead.
252+
*/
253+
function hanota(A: number[], B: number[], C: number[]): void {
254+
const dfs = (n: number, a: number[], b: number[], c: number[]) => {
255+
if (n === 1) {
256+
c.push(a.pop()!);
257+
return;
258+
}
259+
dfs(n - 1, a, c, b);
260+
c.push(a.pop()!);
261+
dfs(n - 1, b, a, c);
262+
};
263+
dfs(A.length, A, B, C);
264+
}
265+
```
47266

267+
```ts
268+
/**
269+
Do not return anything, modify C in-place instead.
270+
*/
271+
function hanota(A: number[], B: number[], C: number[]): void {
272+
const stk: any[] = [[A.length, A, B, C]];
273+
while (stk.length) {
274+
const [n, a, b, c] = stk.pop()!;
275+
if (n === 1) {
276+
c.push(a.pop());
277+
} else {
278+
stk.push([n - 1, b, a, c]);
279+
stk.push([1, a, b, c]);
280+
stk.push([n - 1, a, c, b]);
281+
}
282+
}
283+
}
48284
```
49285

50286
### **...**

0 commit comments

Comments
 (0)