1. [1,2,3,null,4] -> 3
  2. [1] -> 1
  3. [1,2,3] -> 2
  4. 完全二分木 [1..7] -> 3
  5. [1,null,2,null,null,null,3] -> 3
  6. [5,3,8,1,4,null,9] -> 3
コース一覧
コンピューターサイエンス上級:アルゴリズムとデータ構造
二分木の高さ

コンピューターサイエンス上級:アルゴリズムとデータ構造

探索、ソート、木、グラフ、動的計画法、貪欲法など、競技プログラミングや技術面接で問われる高度なアルゴリズムとデータ構造を学べるコースです。基本的な CS の知識を持ち、アルゴリズム力を伸ばしたい学習者や、外資・大手の技術面接対策をしたい方を対象としています。約 13 時間 (1 日 30 分 × 26 日) で 50 レッスンを修了でき、修了後はコーディング面接の実装問題を構造的に解けるようになります。

1
連結リスト
01. リンクリスト構築と長さの計算5分
02. リンクリストの反転5分
03. リンクリストのサイクル検出5分
04. ソート済みリンクリストの merge5分
05. リンクリストの中央ノード取得5分
06. ソート済みリストの重複削除5分
07. 第1章まとめクイズ5分
2
二分木
01. 二分木の in-order 走査5分
02. 二分木の pre-order 走査5分
03. 二分木の post-order 走査5分
04. 二分木の幅優先走査 (BFS)5分
05. 二分木の高さ5分
06. 二分木の平衡判定5分
07. 第2章まとめクイズ — 二分木5分
3
探索木 (BST)
01. BST に値を挿入する5分
02. BST から値を検索する5分
03. BST の最小値と最大値5分
04. BST 妥当性チェック5分
05. BST で k 番目に小さい値5分
06. BST から値を削除する5分
07. 第 3 章 まとめクイズ5分
4
ハッシュとセット
01. hashmap で頻度集計5分
02. キーでグループ化5分
03. two sum (hash で O(n))5分
04. 部分配列の和 = k の個数5分
05. 最長連続部分列5分
06. 集合の積 (intersection)5分
07. 第4章まとめクイズ5分
5
グラフ
01. グラフ BFS で連結成分サイズを求める5分
02. グラフ DFS で連結成分の数を数える5分
03. グラフのパス存在判定5分
04. BFS で最短経路の長さを求める5分
05. トポロジカルソート5分
06. 2 部グラフ判定5分
07. ダイクストラ法 — 重み付きグラフの最短経路15分
08. 第5章まとめクイズ — グラフ5分
6
動的計画法 (上級)
01. 編集距離 (レーベンシュタイン距離)5分
02. 最長増加部分列(LIS)の解法 ── AOJ 2430 対応の動的計画法5分
03. 最大部分配列和 (Kadane)5分
04. 隣り合わない最大値 (House Robber)5分
05. グリッド経路数 (Unique Paths)5分
06. 単語分割可能か (Word Break)5分
07. 第6章まとめクイズ — 動的計画法 (上級)5分
7
総合データ構造と関数型
01. map と filter を組み合わせる5分
02. reduce で積を計算5分
03. 関数合成5分
04. カリー化5分
05. trie の単純検索 (prefix マッチ)5分
06. Union-Find (連結成分数)5分
07. 最終総まとめクイズ5分

二分木の高さ

木の高さは、根から一番深い葉まで何段あるかです。この数がそのまま、探すときに最悪何回たどるかになります。同じ件数を入れても、段数が伸びた木はそれだけ遅い木です。

上から数えると、どの枝が一番長いか最後まで決まらない

根から 1 段ずつ数えていっても、分かれ道のたびに「こちらのほうが長いかもしれない」が残ります。全部の葉まで降りて、届いた深さを覚えておいて、最後に一番大きいものを選ぶ。覚えておく場所が要りますし、書き方も回りくどくなります。

向きを変えます。自分で数えるのをやめて、子に聞くのです。

下に聞いてから、自分の 1 段を足す

まず、高さではなくノードの個数を数える形で見てみます。

Python

def size(node): if node is None: return 0 return 1 + size(node.left) + size(node.right)

JavaScript

function size(node) { if (node === null) return 0; return 1 + size(node.left) + size(node.right); }

自分では 1 つも数えていません。左に何個あるか聞き、右に何個あるか聞き、返ってきた数に自分のぶんの 1 を足して返すだけです。行き止まりが 0 を返すので、葉は 1 を返し、その親は 3 を返し、と下から積み上がっていきます。

聞かれた側が答えを返すだけなので、途中経過をどこかに覚えておく必要がありません。呼び出しから戻ってきた値はその場で使われて消えます。上から数えようとしたときに要った置き場が、まるごと不要になりました。

高さも同じ形で書けます。違うのは、左右から返ってきた 2 つの数をどう扱うかだけです。個数なら両方足しますが、高さは一番深いところまでの段数なので、2 つのうち片方しか使いません。どちらを使うかは、高さの定義をもう一度読めば決まります。

1 の下に 2 と 3 があり、2 の下に 4 だけがある木で追ってみます。4 は子がいないので、下からは 0 が 2 つ返り、自分のぶんを足して 1。3 も同じく 1 です。2 は左が 0、右が 1 なので、深いほうの 1 に自分のぶんを足して 2。根は左が 2、右が 1 なので、深いほうの 2 に足して 3 になります。

空を 0 にするか 1 にするか

行き止まりが返す値の決め方で、答えが 1 つずれます。

プレーンテキスト

空の木 -> 0 葉が 1 つだけ -> 1

このコースでは段の数、つまり通るノードの個数で数えます。自分のぶんの 1 を足し忘れると、段の数ではなく枝の本数を返すことになり、葉が 0、空が -1 という別の流儀になります。どちらも世の中で使われている数え方なので、他人のコードを読むときは、まず空のときに何を返しているかを見てください。

段数を気にする理由は最初に書いたとおりです。100 万件を入れても、きれいに枝分かれしていれば 20 段ほどで底に着き、一直線に伸びていれば 100 万段になります。同じデータ、同じ探し方でも、形だけでこれだけ違います。

要件

  1. tree は BFS 順の配列で、null (Python では None) は欠損ノードを表す
  2. ノードがない場合は高さ 0、ノード 1 つの場合は高さ 1 を返す
  3. 再帰または反復で実装すること

入出力例

height([1,2,3,null,4]) → 3 height([1]) → 1 height([1,2,3]) → 2 height([1,2,3,4,5,6,7]) → 3 height([1,null,2,null,null,null,3]) → 3 height([5,3,8,1,4,null,9]) → 3

ヒント

再帰関数 visit(i) を作り、範囲外 or null なら 0、それ以外なら 1 + max(visit(left), visit(right)) を返す

+1 を忘れると辺の数になってしまうので注意

反復で書きたければ BFS でレベルごとに進めた回数を数える

生田 陸人
監修生田 陸人
ゆめさくエンジニア / 現役ソフトウェアエンジニア監修者プロフィールを見る →
編集 ゆめさく編集部·公開 2026/05/19·更新 2026/08/26

関連レッスン

  • 二分木の平衡判定

    二分木を配列表現で受け取り、すべてのノードで左右部分木の高さの差が 1 以下なら true を返す関数を実装する。

  • 第2章まとめクイズ — 二分木

    二分木の走査 (in-order / pre-order / post-order / BFS) と高さ・平衡判定について理解度を確認する。

  • BST に値を挿入する

    二分探索木 (BST) に新しい値を挿入し、挿入後の in-order 走査結果を配列で返す関数を実装する。

  • hashmap で頻度集計

    配列の各要素が何回現れたかを `hashmap` で集計し、最も多く出た値を返す関数を実装する。

このレッスンに出てくる用語

意味があいまいなまま進んだ語は、ここから読み直せます。

  • treeディレクトリ構造をツリー表示するコマンド
  • 配列サイズ固定の同型データの集まり
  • None「値がない」ことを表す特別な値。
  • 再帰関数が自分自身を呼び出す処理パターン
  • 反復色やフォントを繰り返して秩序を生む
main.py
学習モード
エディタを読み込んでいます

メモ

二分木の高さ

⌘S で保存