Pythonで左右の部分木の入れ替えにより2つの二分木を一致させられるか判定する方法
問題の概要
2つの二分木が与えられたとき、任意のノードについて左部分木と右部分木を何度でも入れ替えてよいと仮定します。この操作を繰り返すことで、1つ目の木を2つ目の木とまったく同じ形に変換できるかどうかを判定するのが、この記事で扱う問題です。
例えば、次のような2つの木が入力として与えられた場合、左右の入れ替えによって一致させられるため、出力は True になります。

解決のアプローチ
この問題は、幅優先探索(BFS)の考え方を使い、木をレベル(深さ)ごとに処理しながらノードの値を比較することで解けます。左右の入れ替えによって同じレベル内の値の並び順は反転し得るため、「順方向」または「逆方向」のどちらかで一致していればよいことになります。
具体的な手順は以下の通りです。
- キュー
que1にroot0を、キューque2にroot1を入れて初期化します。 que1とque2のどちらも空でない限り、次の処理を繰り返します。- 次のレベル用の一時リスト
temp1・temp2と、現在のレベルの値を集めるリストvalues1・values2を用意します。 - 2つのキューの要素数が異なる場合は、木の構造が対応していないため False を返します。
- 各キューの要素について、ノードの値を
values1・values2に追加します。また、子ノードは「右 → 左」の順でtemp1・temp2に登録します。これは、左右の入れ替えによって並びが反転することを考慮するためです。 values1とvalues2が一致せず、さらにvalues1を逆順にしたものとも一致しない場合は False を返します。que1・que2をそれぞれtemp1・temp2で更新し、次のレベルへ進みます。
- 次のレベル用の一時リスト
- すべてのレベルの比較を通過できれば True を返します。
Pythonでの実装例
class TreeNode:
def __init__(self, data, left=None, right=None):
self.val = data
self.left = left
self.right = right
class Solution:
def solve(self, root0, root1):
que1 = [root0]
que2 = [root1]
while que1 and que2:
temp1 = []
temp2 = []
values1 = []
values2 = []
if len(que1) != len(que2):
return False
for i in range(len(que1)):
values1.append(que1[i].val)
values2.append(que2[i].val)
if que1[i].right:
temp1.append(que1[i].right)
if que1[i].left:
temp1.append(que1[i].left)
if que2[i].right:
temp2.append(que2[i].right)
if que2[i].left:
temp2.append(que2[i].left)
if values1 != values2:
if values1 != values2[::-1]:
return False
que1 = temp1
que2 = temp2
return True
ob = Solution()
root = TreeNode(2)
root.right = TreeNode(4)
root.right.left = TreeNode(3)
root.right.right = TreeNode(5)
root1 = TreeNode(2)
root1.left = TreeNode(4)
root1.left.left = TreeNode(3)
root1.left.right = TreeNode(5)
print(ob.solve(root, root1))
入力
root = TreeNode(2)
root.right = TreeNode(4)
root.right.left = TreeNode(3)
root.right.right = TreeNode(5)
root1 = TreeNode(2)
root1.left = TreeNode(4)
root1.left.left = TreeNode(3)
root1.left.right = TreeNode(5)
出力
True
結果の解説
1つ目の木では、根ノード 2 の右側に 4 がぶら下がり、その下に 3(左)と 5(右)が配置されています。一方、2つ目の木では 4 が根の左側に移っていますが、4 の子の並び(3 が左、5 が右)は変わっていません。
つまり、根ノード 2 の左右の部分木を一度入れ替えるだけで2つの木は完全に一致するため、プログラムは True を返します。このように、レベルごとの値の並びが順方向・逆方向のいずれかで一致しているかを確認するだけで、左右の入れ替えによる変換の可否を効率的に判定できます。
-
【Python】二分木が別の木の部分木(サブツリー)かどうかを判定する方法
はじめにプログラミングにおいて、ある二分木が別の二分木の部分木(サブツリー)であるかどうかを判定する処理は、よく登場する基本的な課題の一つです。この記事では、Pythonを使ってこの問題を効率的に解く方法を、具体的なコード例とともにわかりやすく解説します。問題の概要2つの二分木が与えられたとき、「2つ目の木が1つ目の木の部分木になっているか」を確認します。たとえば、次のような入力があった場合:この場合、root2(値4を根とする木)は root1 の中にそのまま含まれているため、出力は True になります。解法のアプローチこの問題は再帰(recursion)を使うことでシンプルに解けます。判
-
Pythonで二分木が完全二分木かどうかを判定するプログラム
完全二分木とは二分木が与えられたとき、その木が完全二分木(complete binary tree)であるかどうかを判定することを考えます。完全二分木とは、最後のレベルを除くすべてのレベルがノードで埋め尽くされており、最後のレベルのノードはすべて可能な限り左側に寄せられている二分木のことです。例えば、次のような二分木が入力として与えられた場合、出力は True になります。アルゴリズム(BFSによる判定方法)この問題は、幅優先探索(BFS)を使って効率的に解けます。木をレベル順に走査し、初めて空のノード(None)が出現した後に再びノードが出現したら、その木は完全二分木ではないと判断できます。