From 8b66bda0fc9b4cd7381bdd8ada74b044153f271d Mon Sep 17 00:00:00 2001 From: tom4649 Date: Thu, 19 Mar 2026 07:47:38 +0900 Subject: [PATCH 1/4] 98. Validate Binary Search Tree --- 98/memo.md | 17 +++++++++++++++++ 98/sol1_dfs_recursion.py | 25 +++++++++++++++++++++++++ 98/sol2_dfs_stack.py | 26 ++++++++++++++++++++++++++ 98/sol3_inorder.py | 32 ++++++++++++++++++++++++++++++++ 4 files changed, 100 insertions(+) create mode 100644 98/memo.md create mode 100644 98/sol1_dfs_recursion.py create mode 100644 98/sol2_dfs_stack.py create mode 100644 98/sol3_inorder.py diff --git a/98/memo.md b/98/memo.md new file mode 100644 index 0000000..aa578ec --- /dev/null +++ b/98/memo.md @@ -0,0 +1,17 @@ +# 98. Validate Binary Search Tree + +- 再帰 dfsで書いた: sol1_dfs_recursion.py +- 色々な解法: https://github.com/mamo3gr/arai60/blob/98_validate-binary-search-tree/98_validate-binary-search-tree/memo.md +- inorderに探索し、昇順になっているかを確認するのかでもとける + - inorder + 再帰 + - https://github.com/nittoco/leetcode/pull/35/changes/BASE..cf57a354ba6d4fd06a3454283c3cec50011ce0c4#r1739978684 + - inorder + stackで書いてみる sol3 + +- 帰りがけ iterative + - https://github.com/naoto-iwase/leetcode/pull/33#discussion_r2479195403 + - これは自分で書けそうにない + - 親の left or rightに新しいノードが加えられる + +- stack dfs + - https://github.com/mamo3gr/arai60/blob/98_validate-binary-search-tree/98_validate-binary-search-tree/step3.py + - 書いてみる: sol2 diff --git a/98/sol1_dfs_recursion.py b/98/sol1_dfs_recursion.py new file mode 100644 index 0000000..853ec2e --- /dev/null +++ b/98/sol1_dfs_recursion.py @@ -0,0 +1,25 @@ +from typing import Optional + + +# Definition for a binary tree node. +class TreeNode: + def __init__(self, val=0, left=None, right=None): + self.val = val + self.left = left + self.right = right + + +class Solution: + def isValidBST(self, root: Optional[TreeNode]) -> bool: + def isValidBST_with_range(node, lower_bound, upper_bound): + if node is None: + return True + if node.val <= lower_bound or node.val >= upper_bound: + return False + return isValidBST_with_range( + node.left, lower_bound, min(upper_bound, node.val) + ) and isValidBST_with_range( + node.right, max(lower_bound, node.val), upper_bound + ) + + return isValidBST_with_range(root, -float("inf"), float("inf")) diff --git a/98/sol2_dfs_stack.py b/98/sol2_dfs_stack.py new file mode 100644 index 0000000..6e79eab --- /dev/null +++ b/98/sol2_dfs_stack.py @@ -0,0 +1,26 @@ +from typing import Optional + + +# Definition for a binary tree node. +class TreeNode: + def __init__(self, val=0, left=None, right=None): + self.val = val + self.left = left + self.right = right + + +class Solution: + def isValidBST(self, root: Optional[TreeNode]) -> bool: + if root is None: + return True + + frontiers = [(root, -float("inf"), float("inf"))] + while frontiers: + node, lower_bound, upper_bound = frontiers.pop() + if not lower_bound < node.val < upper_bound: + return False + if node.left is not None: + frontiers.append((node.left, lower_bound, node.val)) + if node.right is not None: + frontiers.append((node.right, node.val, upper_bound)) + return True diff --git a/98/sol3_inorder.py b/98/sol3_inorder.py new file mode 100644 index 0000000..54a8f9c --- /dev/null +++ b/98/sol3_inorder.py @@ -0,0 +1,32 @@ +from typing import Optional + + +# Definition for a binary tree node. +class TreeNode: + def __init__(self, val=0, left=None, right=None): + self.val = val + self.left = left + self.right = right + + +class Solution: + def isValidBST(self, root: Optional[TreeNode]) -> bool: + frontiers = [] + + def push_it_and_left_children(node): + if node is None: + return + while node.left is not None: + frontiers.append(node) + node = node.left + + push_it_and_left_children(root) + min_value = -float("inf") + while frontiers: + node = frontiers.pop() + if min_value >= node.val: + return False + min_value = node.val + if node.right is not None: + push_it_and_left_children(node.right) + return True From 9c5a5d17a5e8a6b9c283ec6c1b7ef360294b5cc4 Mon Sep 17 00:00:00 2001 From: tom4649 Date: Thu, 19 Mar 2026 08:37:33 +0900 Subject: [PATCH 2/4] Add url --- 98/memo.md | 1 + 1 file changed, 1 insertion(+) diff --git a/98/memo.md b/98/memo.md index aa578ec..ebdb82c 100644 --- a/98/memo.md +++ b/98/memo.md @@ -1,4 +1,5 @@ # 98. Validate Binary Search Tree +[リンク](https://leetcode.com/problems/validate-binary-search-tree/submissions/1952536263/) - 再帰 dfsで書いた: sol1_dfs_recursion.py - 色々な解法: https://github.com/mamo3gr/arai60/blob/98_validate-binary-search-tree/98_validate-binary-search-tree/memo.md From f93dc40829917da3eee5c44971d591d481791a72 Mon Sep 17 00:00:00 2001 From: tom4649 Date: Thu, 26 Mar 2026 07:05:29 +0900 Subject: [PATCH 3/4] Fix sol3.py --- 98/sol3_inorder.py | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/98/sol3_inorder.py b/98/sol3_inorder.py index 54a8f9c..816a20c 100644 --- a/98/sol3_inorder.py +++ b/98/sol3_inorder.py @@ -14,9 +14,7 @@ def isValidBST(self, root: Optional[TreeNode]) -> bool: frontiers = [] def push_it_and_left_children(node): - if node is None: - return - while node.left is not None: + while node is not None: frontiers.append(node) node = node.left @@ -27,6 +25,5 @@ def push_it_and_left_children(node): if min_value >= node.val: return False min_value = node.val - if node.right is not None: - push_it_and_left_children(node.right) + push_it_and_left_children(node.right) return True From 4aa5eb7c407086d5c7610d1402465ea37a3a0640 Mon Sep 17 00:00:00 2001 From: tom4649 Date: Thu, 26 Mar 2026 07:51:05 +0900 Subject: [PATCH 4/4] Add suggested changes --- 98/sol1_dfs_recursion.py | 10 ++++------ 98/sol2_dfs_stack.py | 13 +++++++------ 98/sol3_inorder.py | 8 ++++---- 3 files changed, 15 insertions(+), 16 deletions(-) diff --git a/98/sol1_dfs_recursion.py b/98/sol1_dfs_recursion.py index 853ec2e..04c7bf3 100644 --- a/98/sol1_dfs_recursion.py +++ b/98/sol1_dfs_recursion.py @@ -11,15 +11,13 @@ def __init__(self, val=0, left=None, right=None): class Solution: def isValidBST(self, root: Optional[TreeNode]) -> bool: - def isValidBST_with_range(node, lower_bound, upper_bound): + def isValidBST_with_range(node, must_be_greater_than, must_be_less_than): if node is None: return True - if node.val <= lower_bound or node.val >= upper_bound: + if node.val <= must_be_greater_than or node.val >= must_be_less_than: return False return isValidBST_with_range( - node.left, lower_bound, min(upper_bound, node.val) - ) and isValidBST_with_range( - node.right, max(lower_bound, node.val), upper_bound - ) + node.left, must_be_greater_than, node.val + ) and isValidBST_with_range(node.right, node.val, must_be_less_than) return isValidBST_with_range(root, -float("inf"), float("inf")) diff --git a/98/sol2_dfs_stack.py b/98/sol2_dfs_stack.py index 6e79eab..2ae9f3c 100644 --- a/98/sol2_dfs_stack.py +++ b/98/sol2_dfs_stack.py @@ -14,13 +14,14 @@ def isValidBST(self, root: Optional[TreeNode]) -> bool: if root is None: return True - frontiers = [(root, -float("inf"), float("inf"))] - while frontiers: - node, lower_bound, upper_bound = frontiers.pop() - if not lower_bound < node.val < upper_bound: + frontier = [(root, -float("inf"), float("inf"))] + while frontier: + node, must_be_greater_than, must_be_less_than = frontier.pop() + if not must_be_greater_than < node.val < must_be_less_than: return False if node.left is not None: - frontiers.append((node.left, lower_bound, node.val)) + frontier.append((node.left, must_be_greater_than, node.val)) if node.right is not None: - frontiers.append((node.right, node.val, upper_bound)) + frontier.append((node.right, node.val, must_be_less_than)) + return True diff --git a/98/sol3_inorder.py b/98/sol3_inorder.py index 816a20c..a7b924d 100644 --- a/98/sol3_inorder.py +++ b/98/sol3_inorder.py @@ -11,17 +11,17 @@ def __init__(self, val=0, left=None, right=None): class Solution: def isValidBST(self, root: Optional[TreeNode]) -> bool: - frontiers = [] + frontier = [] def push_it_and_left_children(node): while node is not None: - frontiers.append(node) + frontier.append(node) node = node.left push_it_and_left_children(root) min_value = -float("inf") - while frontiers: - node = frontiers.pop() + while frontier: + node = frontier.pop() if min_value >= node.val: return False min_value = node.val