Pythonで二分木の直径を求める方法【DFSを使った実装解説】
二分木の直径とは
二分木が与えられたとき、その木の直径(diameter)を計算することを考えます。二分木の直径とは、木の中の任意の2つのノードをつなぐ最長経路の長さのことです。
重要なポイントとして、この経路は必ずしも根(ルート)を通るとは限りません。
例えば、次のような木を考えてみましょう。

この場合、経路 [4, 2, 1, 3] または [5, 2, 1, 3] の長さが3本の辺で構成されているため、直径は3となります。
解法のアプローチ
この問題はDFS(深さ優先探索)を使うことで効率的に解くことができます。手順は以下の通りです。
- DFSで各ノードを訪問しながら直径を求めます。まず答えを格納する変数を
answer = 0で初期化します。 - ルートノードに対して
dfs(root)を呼び出します。 dfs(node)は以下のように動作します。- ノードが存在しない場合は
0を返します。 left:= 左部分木に対するDFSの結果、right:= 右部分木に対するDFSの結果を取得します。answer:=max(answer, left + right)として更新します。これは「現在のノードを頂点とした左右の経路の合計」が直径の候補になるためです。- 親ノードに返す値は
max(left + 1, right + 1)です。これは「そのノードから下方向へ伸びる最長の深さ」を表します。
Pythonでの実装例
それでは、実際のコードを見てみましょう。
class TreeNode:
def __init__(self, data, left=None, right=None):
self.data = data
self.left = left
self.right = right
def insert(temp, data):
que = []
que.append(temp)
while len(que):
temp = que[0]
que.pop(0)
if not temp.left:
temp.left = TreeNode(data)
break
else:
que.append(temp.left)
if not temp.right:
temp.right = TreeNode(data)
break
else:
que.append(temp.right)
def make_tree(elements):
Tree = TreeNode(elements[0])
for element in elements[1:]:
insert(Tree, element)
return Tree
class Solution(object):
def diameterOfBinaryTree(self, root):
"""
:type root: TreeNode
:rtype: int
"""
self.ans = 0
self.dfs(root)
return self.ans
def dfs(self, node):
if not node:
return 0
left = self.dfs(node.left)
right = self.dfs(node.right)
self.ans = max(self.ans, right + left)
return max(left + 1, right + 1)
root = make_tree([1, 2, 3, 4, 5])
ob1 = Solution()
print(ob1.diameterOfBinaryTree(root))入力
[1, 2, 3, 4, 5]
出力
3
計算量について
- 時間計算量: O(n) — 各ノードを一度だけ訪問するためです(n はノード数)。
- 空間計算量: O(h) — 再帰呼び出しのスタックの深さに依存します(h は木の高さ)。木が偏っている場合は最大でO(n)になります。
まとめ
二分木の直径を求める問題では、「各ノードを根とした左右の深さの合計」をDFSで順番に計算し、その最大値を記録していくのがポイントです。経路がルートを通らないケースにも対応できるよう、答えの更新を再帰処理の中で行っている点に注目してください。
-
Pythonで二分木を反転する方法:再帰を使った実装を解説
二分木の反転とは二分木が与えられたとき、その左右の子ノードを入れ替えて「鏡像」のような木を作ることを二分木の反転(Invert Binary Tree)と呼びます。これはアルゴリズムの学習やコーディング面接でも頻出のトピックです。例えば、次のような二分木があったとします。これを反転すると、すべてのノードの左部分木と右部分木が入れ替わり、以下のような木になります。解き方:再帰的アプローチこの問題は再帰を使うと非常にシンプルに解けます。考え方は以下の3ステップです。ルートが None(null)であれば、そのまま返す(ベースケース)現在のノードの左ポインタと右ポインタを入れ替える左部分木と右部分木
-
Pythonで二分木の最大深度を求める方法|再帰を使った実装例を解説
Pythonで二分木の最大深度を求める二分木が与えられたとき、その最大深度を求める問題を考えます。木の最大深度とは、根(ルート)から葉ノードまでの最も長い経路をたどったときに通過するノード数のことです。例えば、下図のような二分木の場合、最大深度は 3 となります。解法のアプローチこの問題は再帰を使うことで、非常にシンプルに解くことができます。手順は以下のとおりです。再帰用のヘルパーメソッド solve(root, depth=0) を定義します。root が空(None)の場合は、そこまでの深さ depth をそのまま返します。それ以外の場合は、左部分木に対する solve(left, dep