From eed5b804cdd89bcc83e568872fe223953ad955b8 Mon Sep 17 00:00:00 2001 From: Masakuni Date: Thu, 19 Feb 2026 19:03:44 +0900 Subject: [PATCH 1/3] step1 --- .../98.validate-binary-search-tree/memo.md | 14 +++++++ .../98.validate-binary-search-tree/step1.py | 42 +++++++++++++++++++ 2 files changed, 56 insertions(+) create mode 100644 problems/98.validate-binary-search-tree/memo.md create mode 100644 problems/98.validate-binary-search-tree/step1.py diff --git a/problems/98.validate-binary-search-tree/memo.md b/problems/98.validate-binary-search-tree/memo.md new file mode 100644 index 0000000..349addd --- /dev/null +++ b/problems/98.validate-binary-search-tree/memo.md @@ -0,0 +1,14 @@ +## step1 +- 最後にleft,rightに行った箇所が重要な気がした + - 常に下記を満たす必要がある + - 最後にleftに行った箇所のval未満でなければならない + - 最後にrightに行った箇所のvalを超える値でなければならない + - 幅優先探索をする + - 管理するnodeとless_than,more_thanを管理すれば良さそう + - NoneはTrueなのかFalseなのか + - `The number of nodes in the tree is in the range [1, 10^4].`となっているが、型はOptional + - 一旦Noneも入る想定にする + - 個人的にはFalseにしたい + - Trueの判定を行なった後でNoneのことを考慮したくない +- 10分ほどでかけた + diff --git a/problems/98.validate-binary-search-tree/step1.py b/problems/98.validate-binary-search-tree/step1.py new file mode 100644 index 0000000..e0dd9aa --- /dev/null +++ b/problems/98.validate-binary-search-tree/step1.py @@ -0,0 +1,42 @@ +# +# @lc app=leetcode id=98 lang=python3 +# +# [98] Validate Binary Search Tree +# + +# @lc code=start +# 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 False + + more_than = -float("inf") + less_than = float("inf") + level_nodes_with_range = [(root, more_than, less_than)] + + while level_nodes_with_range: + next_level_nodes_with_range = [] + for node, more_than, less_than in level_nodes_with_range: + is_valid_bst_node = more_than < node.val < less_than + + if not is_valid_bst_node: + return False + + if node.left is not None: + next_level_nodes_with_range.append((node.left, more_than, node.val)) + if node.right is not None: + next_level_nodes_with_range.append( + (node.right, node.val, less_than) + ) + level_nodes_with_range = next_level_nodes_with_range + + return True + + +# @lc code=end From 12d33a20a0e81ac2322f1248afccef16699585ff Mon Sep 17 00:00:00 2001 From: Masakuni Date: Thu, 19 Feb 2026 19:04:05 +0900 Subject: [PATCH 2/3] step2 --- .../98.validate-binary-search-tree/memo.md | 26 ++++++++++++ .../98.validate-binary-search-tree/step2.py | 40 +++++++++++++++++++ 2 files changed, 66 insertions(+) create mode 100644 problems/98.validate-binary-search-tree/step2.py diff --git a/problems/98.validate-binary-search-tree/memo.md b/problems/98.validate-binary-search-tree/memo.md index 349addd..f16dfa3 100644 --- a/problems/98.validate-binary-search-tree/memo.md +++ b/problems/98.validate-binary-search-tree/memo.md @@ -12,3 +12,29 @@ - Trueの判定を行なった後でNoneのことを考慮したくない - 10分ほどでかけた +## step2 +- 再帰でも書ける気はする + - どれか1つでもFalseになったらダメなので`and`で繋いでいけば良い? + - 一旦書いてみる + - 10分ほどで書けたがhelperの子の有無をもっと上手く書けるかもしれない + - 数字の判定を先に書くことでFalseが入った場合に早めに打ち切られるようにした +- 他の人のコードを見る +- https://github.com/mamo3gr/arai60/pull/26 +``` +ところで `root is None` なときはどちらなんだろうか。もはや木ですらないし、比較する値もないが…。 +→Geminiと議論したところ、空の木は二分探索木としてよいみたい。理屈としては、ノードがひとつだけの木を考えたとき、そのsubtreeも二分探索木なはずで、subtree=空の木だから。 +Web上の資料を探してもらったが、明確に定義としてそう書いてあるものは見つけられなかった。 +``` + - 同じ部分が気にできていたが、結論は違っていた。`そのsubtreeも二分探索木なはず`これは確かに + - `何が分かりにくいかを言語化しておく。`こういう姿勢を持てるようになりたい + - `inf`をmath.infでも書けるのは知っておく +- https://github.com/huyfififi/coding-challenges/pull/39/changes#diff-ac2b937f26131bdaf8a2c0d3709d0befa4ae53c7efb9f6efbceb62567acc9c75 + - `if node is None: continue`これは選択肢になかった。子がNoneの場合でも追加しておいて、チェックする際にcontinueする方法 +- https://github.com/plushn/SWE-Arai60/pull/28/changes + - `yield_from`知らなかった + - https://docs.python.org/3.14/reference/expressions.html#grammar-token-python-grammar-yield_from + - 再帰に苦手意識があるので組み合わさると結構読む時に身構えてしまう +- https://github.com/Kaichi-Irie/leetcode-python/pull/29/changes + - `Noneチェックはpop後にやる他、append前にやる方法もあります。一応速度の面ではappend前にやった方がわずか速いことになりますが、趣味の範囲だと思います。pop後にやる方が大抵コードはシンプルになる気がします。`先ほどの気づきが一般化されて言語化されていた。このように言語化して理解していきたい。 + + diff --git a/problems/98.validate-binary-search-tree/step2.py b/problems/98.validate-binary-search-tree/step2.py new file mode 100644 index 0000000..54065a4 --- /dev/null +++ b/problems/98.validate-binary-search-tree/step2.py @@ -0,0 +1,40 @@ +# +# @lc app=leetcode id=98 lang=python3 +# +# [98] Validate Binary Search Tree +# + +# @lc code=start +# 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 False + + def helper(node: TreeNode, more_than: int, less_than: int): + if node.left is None and node.right is None: + return more_than < node.val < less_than + if node.left is None: + return more_than < node.val < less_than and helper( + node.right, node.val, less_than + ) + if node.right is None: + return more_than < node.val < less_than and helper( + node.left, more_than, node.val + ) + + return ( + more_than < node.val < less_than + and helper(node.right, node.val, less_than) + and helper(node.left, more_than, node.val) + ) + + return helper(root, -float("inf"), float("inf")) + + +# @lc code=end From c9e886850411d07dd38cf106bf52eba6e94d6979 Mon Sep 17 00:00:00 2001 From: Masakuni Date: Thu, 19 Feb 2026 19:04:18 +0900 Subject: [PATCH 3/3] step3 --- .../98.validate-binary-search-tree/memo.md | 3 ++ .../98.validate-binary-search-tree/step3.py | 41 +++++++++++++++++++ 2 files changed, 44 insertions(+) create mode 100644 problems/98.validate-binary-search-tree/step3.py diff --git a/problems/98.validate-binary-search-tree/memo.md b/problems/98.validate-binary-search-tree/memo.md index f16dfa3..56f8ce3 100644 --- a/problems/98.validate-binary-search-tree/memo.md +++ b/problems/98.validate-binary-search-tree/memo.md @@ -37,4 +37,7 @@ Web上の資料を探してもらったが、明確に定義としてそう書 - https://github.com/Kaichi-Irie/leetcode-python/pull/29/changes - `Noneチェックはpop後にやる他、append前にやる方法もあります。一応速度の面ではappend前にやった方がわずか速いことになりますが、趣味の範囲だと思います。pop後にやる方が大抵コードはシンプルになる気がします。`先ほどの気づきが一般化されて言語化されていた。このように言語化して理解していきたい。 +## step3 +- step1の変数名を修正した +- 処理時にNoneの判定をするようにした diff --git a/problems/98.validate-binary-search-tree/step3.py b/problems/98.validate-binary-search-tree/step3.py new file mode 100644 index 0000000..8f8a3ce --- /dev/null +++ b/problems/98.validate-binary-search-tree/step3.py @@ -0,0 +1,41 @@ +# +# @lc app=leetcode id=98 lang=python3 +# +# [98] Validate Binary Search Tree +# + +# @lc code=start +# 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 + + more_than = -float("inf") + less_than = float("inf") + current_level_nodes_with_range = [(root, more_than, less_than)] + + while current_level_nodes_with_range: + next_level_nodes_with_range = [] + for node, more_than, less_than in current_level_nodes_with_range: + if node is None: + continue + + valid_bst_node = more_than < node.val < less_than + if not valid_bst_node: + return False + + next_level_nodes_with_range.append((node.left, more_than, node.val)) + next_level_nodes_with_range.append((node.right, node.val, less_than)) + + current_level_nodes_with_range = next_level_nodes_with_range + + return True + + +# @lc code=end