blog

LeetCode 104. バイナリツリーの最大深度|Python

104. 二分木の最大深度 二分木が与えられたとき、その最大深度を求めなさい。 二分木の深さとは、ルートノードから最も遠いリーフノードまでの最長経路上のノードの数。 注意:葉ノードとは,子を持たないノ...

Feb 2, 2020 · 3 min. read
シェア

二分木の最大深さ

問題出典:パワーバックル

問題

二分木が与えられたとき、その最大深さを求めなさい。

二分木の深さは、ルート・ノードから最も遠いリーフ・ノードまでの最長経路上のノードの数です。

説明: リーフノードとは、子を持たないノードのことです。

二分木が与えられたとき[3,9,20,null,null,15,7],
 3
 / \
 9 20
 / \
 15 7
最大深度3を返す。

問題解決のアイデア

アイデア:再帰、幅優先探索

この問題では、二分木の深さはルートノードから最も遠いリーフノードまでの最長経路上のノードの数であることが示唆されています。そこで、再帰と幅優先探索の考え方から問題を解くことを考えます。以下、再帰の考え方から問題を分析し、解いていきます。

再帰的

問題のヒントから、2分木の深さはその左と右の部分木の深さに関係することが知られています。

先ほど言ったように、二分木の深さはルートノードから最も遠いリーフノードまでの最長経路上のノード数ですから、つまり、左の部分木の最大深さと右の部分木の最大深さを求める場合、この2つのうち大きい方の深さにルートノードの深さを足したものが二分木全体の深さになります。つまり、バイナリツリーの最大深さ=左サブツリーと右サブツリーの最大深さの大きい方の深さ+ルートノードの高さです。次の式のように

max_depth = max(left_tree_depth, right_tree_depth) + 1

そこで問題は、左サブツリーと右サブツリーの最大深さをどのように求めるかです。左と右の部分木の最大深さを再帰的に求め、葉ノードに遭遇したときに再帰を終了します。

具体的なコードについては、コードの実装を参照してください。

パン優先探索

ここでは、幅優先探索のアイデアも問題解決に利用できます。ここで、補助待ち行列を追加する必要があります。この補助待ち行列に、現在の層のすべてのノードを格納します。

ここで注意しなければならないのは、次のレイヤーを検索する準備ができたら、現在のレイヤーのすべてのノードをキューに入れ、そのノードに次のレイヤーを検索させる必要があるということです。

そして、現在のレベルのノードがすべてキューから出ていて、キューが空でなければ、次のレベルのノードが残っています。キューが空になるまでループし、変数depthを定義し、各レベルの探索で値を維持・更新し、最終的にdepthがバイナリツリーの必要な最大深度になります。

具体的なコードについてはコードの実装を参照してください # 幅優先探索

コードの実装

#  
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution:
 def maxDepth(self, root: TreeNode) -> int:
 # 終了条件
 if not root:
 return 0
 # 左右の部分木の最大深さを再帰的に計算する
 left_tree_depth = self.maxDepth(root.left)
 right_tree_depth = self.maxDepth(root.right)
 return max(left_tree_depth, right_tree_depth) + 1
# パン優先探索
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution:
 def maxDepth(self, root: TreeNode) -> int:
 # 特殊なケースを扱う
 if not root:
 return 0
 from collections import deque
 # 補助キュー
 queue = deque()
 # バイナリツリーの深さを記録し、維持・更新する,
 depth = 0
 queue.append(root)
 while queue:
 # 現在の階層にあるすべてのノードがリストアップされ、下方向に検索される
 size = len(queue)
 for i in range(size):
 node = queue.popleft()
 if node.left:
 queue.append(node.left)
 if node.right:
 queue.append(node.right)
 depth += 1
 
 return depth

結果の実現

実現結果 # 再帰的

実装結果 # 先頭探索

出版物

Read next

クロスエントロピーのコスト関数に関する見解

I. 2次コスト関数の不適切さ\nANNの設計目的の1つは、機械が人間のように知識を学習できるようにすることです。人が新しい物事を分析することを学ぶとき、より大きな間違いをしたことがわかったら、より大きな修正をします。例えば、バスケットボールをシュートするとき、正しい方向から遠ければ遠いほど、より多くのシュートを打つことができます。

Feb 1, 2020 · 16 min read