mirror of
https://github.com/krahets/hello-algo.git
synced 2026-07-22 19:36:06 +00:00
build
This commit is contained in:
@@ -0,0 +1,132 @@
|
||||
---
|
||||
comments: true
|
||||
---
|
||||
|
||||
<!-- utils/exercises/publish_exercises.py により自動生成されています。直接編集しないでください。 -->
|
||||
|
||||
# 7.7 演習
|
||||
|
||||
## 7.7.1 確認問題
|
||||
|
||||
### 1. 完全二分木・充満二分木・充足二分木
|
||||
|
||||
次の 2 つの配列は二分木をレベル順に表しており、`None` は空き位置を表します。
|
||||
|
||||
- 木 A:`[1, 2, 3, 4, 5, 6]`
|
||||
- 木 B:`[1, 2, 3, None, None, 6, 7]`
|
||||
|
||||
<!-- numbered-subquestions -->
|
||||
|
||||
1. どちらが完全二分木ですか?
|
||||
2. どちらが充満二分木、つまりすべての非葉ノードが 2 つの子ノードを持つ二分木ですか?
|
||||
3. この 2 つに充足二分木はありますか?それぞれ理由を説明してください。
|
||||
|
||||
??? success "解答"
|
||||
|
||||
1. 木 A は完全二分木です。最下層だけがすべて埋まっておらず、ノードが左から右へ隙間なく並んでいます。
|
||||
木 B は完全二分木ではありません。最下層の左側に空き位置がある一方で、その右側にはノードがあるためです。
|
||||
|
||||
2. 木 B は充満二分木です。ノード 1 とノード 3 はそれぞれ 2 つの子ノードを持ち、それ以外のノードはすべて葉ノードです。
|
||||
木 A は充満二分木ではありません。ノード 3 が左子ノード 6 だけを持つためです。
|
||||
|
||||
3. どちらも充足二分木ではありません。どちらの木も最下層がすべて埋まっていないためです。
|
||||
|
||||
### 2. 同じ木を走査する 3 つの順序
|
||||
|
||||
配列 `[1, 2, 3, 4, 5, 6, 7]` をレベル順に完全二分木へ格納します。
|
||||
|
||||
<!-- numbered-subquestions -->
|
||||
|
||||
1. この木を描いてください。
|
||||
2. 先行順・中間順・後行順走査の列をそれぞれ書いてください。
|
||||
3. 中間順走査の列で、根ノード 1 の左側と右側にある 2 つの列は、木のどの部分にそれぞれ対応しますか?
|
||||
|
||||
??? success "解答"
|
||||
|
||||
1. この木は次のとおりです。
|
||||
|
||||
```text
|
||||
1
|
||||
/ \
|
||||
2 3
|
||||
/ \ / \
|
||||
4 5 6 7
|
||||
```
|
||||
|
||||
2. 先行順走査は `1, 2, 4, 5, 3, 6, 7`、
|
||||
中間順走査は `4, 2, 5, 1, 6, 3, 7`、
|
||||
後行順走査は `4, 5, 2, 6, 7, 3, 1` です。
|
||||
|
||||
3. 根ノード 1 の左側にある `4, 2, 5` は、左部分木の中間順走査の列です。
|
||||
右側にある `6, 3, 7` は、右部分木の中間順走査の列です。
|
||||
|
||||
### 3. 2 つの二分探索木を比較する
|
||||
|
||||
次の 2 つの列を、左から右へ順に空の二分探索木へ挿入します。
|
||||
|
||||
- 列 A:`[4, 2, 6, 1, 3, 5, 7]`
|
||||
- 列 B:`[1, 2, 3, 4, 5, 6, 7]`
|
||||
|
||||
<!-- numbered-subquestions -->
|
||||
|
||||
1. それぞれの木で 7 を探索するときに通るノードを書いてください。
|
||||
2. 高さを根ノードから最も遠い葉ノードまでに通る辺の数とすると、2 つの木の高さはそれぞれいくつですか?
|
||||
3. 問い 1、2 の結果から、2 つの木で 7 を探索する効率は同じだと考えられますか?木の形と探索経路をもとに理由を説明してください。
|
||||
|
||||
??? success "解答"
|
||||
|
||||
1. 列 A から作った木では、探索経路は `4 → 6 → 7` です。
|
||||
列 B から作った木では、探索経路は `1 → 2 → 3 → 4 → 5 → 6 → 7` です。
|
||||
|
||||
2. 1 つ目の木はすべての層が埋まっているため、高さは 2 です。2 つ目の木では各ノードが右の子だけを持ち、高さは 6 です。
|
||||
|
||||
3. 2 つの木で 7 を探索する効率は異なります。挿入順序によって二分探索木の形と高さが変わります。1 つ目の木で 7 を探索するときに通るノードは 3 つだけですが、
|
||||
2 つ目の木では 7 つのノードを順に通ります。木が高いほど、最悪の場合に経路上で比較するノードが多くなります。
|
||||
|
||||
## 7.7.2 プログラミング演習
|
||||
|
||||
### 1. 二分木の最大の深さ
|
||||
|
||||
二分木の根ノード `root` が与えられます。各ノードには、整数値と左右の子ノードを指す参照が含まれています。
|
||||
|
||||
根ノードから最も遠い葉ノードまでに通る**ノード数**を、二分木の最大の深さとします。この木の最大の深さを返してください。空の木の最大の深さは 0 です。
|
||||
再帰を使って求めてください。
|
||||
|
||||
??? tip "解法のヒント"
|
||||
|
||||
1. この問題ではノード数で深さを数えます。根ノードだけがある場合、最大の深さは 1 です
|
||||
2. 再帰関数が、現在のノードを根とする部分木の最大の深さを返すようにします
|
||||
3. 空のノードは 0 を返し、空でないノードは max(depth(left), depth(right)) + 1 を返します
|
||||
|
||||
[LeetCode](https://leetcode.com/problems/maximum-depth-of-binary-tree/){ .rounded-button .exercise-button target="_blank" rel="noopener noreferrer" }
|
||||
|
||||
### 2. 二分木のレベル順走査
|
||||
|
||||
二分木の根ノード `root` が与えられます。キューを使い、上から下へ層ごとにすべてのノードを訪問してください。同じ層では、左から右の順に訪問します。
|
||||
|
||||
二次元配列を返してください。1 つ目の部分配列には根ノードがある層のノード値、2 つ目の部分配列には次の層のノード値を保存し、以降も同様に続けます。
|
||||
二分木が空の場合は、空の配列を返してください。
|
||||
|
||||
??? tip "解法のヒント"
|
||||
|
||||
1. レベル順走査では先に入ったノードを先に訪問するため、キューを使います
|
||||
2. 各回の開始時にキューに入っているノードは、ちょうど同じ層に属しています
|
||||
3. 先にキューの長さを記録し、その個数のノードを取り出して、それぞれの子ノードを追加します
|
||||
|
||||
[LeetCode](https://leetcode.com/problems/binary-tree-level-order-traversal/){ .rounded-button .exercise-button target="_blank" rel="noopener noreferrer" }
|
||||
|
||||
### 3. 二分探索木で k 番目に小さい要素
|
||||
|
||||
二分探索木には `n` 個のノードがあり、すべてのノード値は互いに異なります。
|
||||
すべてのノード値を小さい順に並べたときの位置には、1 から番号を付けます。
|
||||
|
||||
根ノード `root` と、`1 <= k <= n` を満たす整数 `k` が与えられます。`k` 番目のノード値を返してください。
|
||||
すべてのノード値を先に集めるのではなく、中間順走査の途中で答えを直接探してください。
|
||||
|
||||
??? tip "解法のヒント"
|
||||
|
||||
1. 二分探索木を中間順走査すると、ノード値を小さい順に訪問できます
|
||||
2. 中間順走査では、左部分木、現在のノード、右部分木の順に処理します。現在のノードを訪問するとき、カウントに 1 を足します
|
||||
3. カウントが初めて k になったとき、現在のノード値が答えです。それ以降は走査を続ける必要がありません
|
||||
|
||||
[LeetCode](https://leetcode.com/problems/kth-smallest-element-in-a-bst/){ .rounded-button .exercise-button target="_blank" rel="noopener noreferrer" }
|
||||
@@ -21,3 +21,4 @@ icon: material/graph-outline
|
||||
- [7.4 二分探索木](binary_search_tree.md)
|
||||
- [7.5 AVL 木 *](avl_tree.md)
|
||||
- [7.6 まとめ](summary.md)
|
||||
- [7.7 演習](exercises.md)
|
||||
|
||||
Reference in New Issue
Block a user