infが分からないという質問からif node.val > node.left.val > lower:
が分からないという質問に変わってしまっているようなので、そちらの説明のために動画のコードから解答例のコードに変形してみましょうか。
動画のコードは以下のようになっていました。
python
1class Solution:
2 def isValidBST(self, root: Optional[TreeNode]) -> bool:
3 def valid(node, left, right):
4 if not node:
5 return True
6 if not (node.val < right and node.val > left):
7 return False
8 return (valid(node.left, left, node.val) and
9 valid(node.right, node.val, right))
10 return valid(root, float("-inf"), float("inf"))
この再帰のコードは、すべてのノードについてvalid
が成立するか確認しているので、BFSに書き換えられます。BFSに書き換えるには、ノードを順番にキューに登録していけばよいですが、今回はノードごとにleft, right
の値が変わるので、そちらもいっしょにキューに登録する必要があります。
python
1class Solution:
2 def isValidBST(self, root: Optional[TreeNode]) -> bool:
3 q = deque()
4 q.append([root, float("-inf"), float("inf")])
5 while q:
6 node, left, right = q.popleft()
7 if not node:
8 continue
9 if not (node.val < right and node.val > left):
10 return False
11 q.append([node.left, left, node.val])
12 q.append([node.right, node.val, right])
13 return True
さて、if not node: continue
の部分に着目すると、node
がNone
の場合は何もしないで読み飛ばしていることが分かります。つまり、node
がNone
のノードをキューに登録するのは無駄です。事前に判定して登録しないようにしましょう。ただし、root
は問題の条件によりNone
でないことが確定しているので判定しません。
python
1class Solution:
2 def isValidBST(self, root: Optional[TreeNode]) -> bool:
3 q = deque()
4 q.append([root, float("-inf"), float("inf")])
5 while q:
6 node, left, right = q.popleft()
7 if not (node.val < right and node.val > left):
8 return False
9 if node.left:
10 q.append([node.left, left, node.val])
11 if node.right:
12 q.append([node.right, node.val, right])
13 return True
次にif not (node.val < right and node.val > left): return False
に着目すると、この条件を満たす場合はそのままFalse
を返していることが分かります。つまり、この条件を満たすノードは、キューに登録しないでいきなりFalse
を返してしまってよいことになります。事前に判定するようにしましょう。ただし、root
はこの条件を満たすことはないので判定しません。
python
1class Solution:
2 def isValidBST(self, root: Optional[TreeNode]) -> bool:
3 q = deque()
4 q.append([root, float("-inf"), float("inf")])
5 while q:
6 node, left, right = q.popleft()
7 if node.left:
8 if not (node.left.val < node.val and node.left.val > left):
9 return False
10 q.append([node.left, left, node.val])
11 if node.right:
12 if not (node.right.val < right and node.right.val > node.val):
13 return False
14 q.append([node.right, node.val, right])
15 return True
あとは、変数名の付け替えと簡単な変形で、解答例の形にもちこめるでしょう。
最後の変形の過程でわかると思いますが、if node.val > node.left.val > lower:
という条件文のそもそもの目的は、node.left
が条件を満たすかどうか事前に判断することにあります。そう考えれば、node.left.val
が中央にあるのも納得できるのではないでしょうか。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。