-
Notifications
You must be signed in to change notification settings - Fork 0
Create 776. Split BST.md #47
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,123 @@ | ||
| # 776. Split BST | ||
| ## STEP1 | ||
| - 何も見ずに解いてみる | ||
| - target 以下で最大の値を持つ node を根にしないといけないと勘違いしておかしなコードを書いた。 | ||
| - target 以下で最大の値を持つ node X を見つける。探索の最中に全ての node の値がtarget より小さい/大きい木をまとめておく。node X に親がいたら切り離し。代わりに node X の right を繋ぐ。 | ||
|
|
||
| おかしいコード | ||
| ```python | ||
| # 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 splitBST(self, root: Optional[TreeNode], target: int) -> List[Optional[TreeNode]]: | ||
| def add_tree_to_left(tree, tree_to_add): | ||
| if tree is None: | ||
| return tree_to_add | ||
| left_node = tree | ||
| while left_node is not None: | ||
| if left_node.left is None: | ||
| left_node.left = tree_to_add | ||
| break | ||
| left_node = left_node.left | ||
| return tree | ||
|
|
||
| smaller_bst = None | ||
| greater_bst = None | ||
| node = root | ||
| while node is not None: | ||
| if node.val == target: | ||
| smaller_bst = add_tree_to_left(node, smaller_bst) | ||
| greater_bst = add_tree_to_left(greater_bst, node.right) | ||
| node.right = None | ||
| break | ||
| if node.val < target: | ||
| smaller_bst = add_tree_to_left(node, smaller_bst) | ||
| next_node = node.right | ||
| node.right = None | ||
| node = next_node | ||
| continue | ||
| if node.val > target: | ||
| greater_bst = add_tree_to_left(greater_bst, node) | ||
| next_node = node.left | ||
| node.left = None | ||
| node = next_node | ||
| return [smaller_bst, greater_bst] | ||
| ``` | ||
|
|
||
| - https://github.com/olsen-blue/Arai60/pull/48/files をみて理解した。 | ||
|
|
||
| ```python | ||
| class Solution: | ||
| def splitBST(self, root: Optional[TreeNode], target: int) -> List[Optional[TreeNode]]: | ||
| if root is None: | ||
| return [None, None] | ||
|
|
||
| if root.val <= target: | ||
| smaller, greater = self.splitBST(root.right, target) | ||
| root.right = smaller | ||
| return [root, greater] | ||
| else: | ||
| smaller, greater = self.splitBST(root.left, target) | ||
| root.left = greater | ||
| return [smaller, root] | ||
| ``` | ||
|
|
||
| ## STEP2 | ||
| ### プルリクやドキュメントを参照 | ||
| - https://github.com/goto-untrapped/Arai60/pull/54#discussion_r1780641914 | ||
| - 具体例の考え方について。私も複雑な例から考えてしまっていた。 | ||
| - コードが書けて正当性について他者に説明できる理解の精度がないといけませんね。 | ||
| - while で書くパターン。 | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 以前小田さんから「再帰とループの中間を念頭において、対応関係から相互に変換できるようにしておくといいでしょう。」とコメントをいただいたことがございます。リンク先にコードもございます🙇
Owner
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 再帰とループの対応は考えてましたが中間というものは考えたことがありませんでした。 |
||
| - 番兵を使う。node_in_smaller_bst は target 以下であることがわかった中で最大の node を指す。今後見つかる target 以下のノードはこれより大きいので right に繋がないといけない。 | ||
| - smaller_bst_root = TreeNode(-math.inf), greater_bst_root = TreeNode(math.inf) と書くと番兵らしさが増しそう? | ||
|
|
||
| ```python | ||
| class Solution: | ||
| def splitBST(self, root: Optional[TreeNode], target: int) -> List[Optional[TreeNode]]: | ||
| node = root | ||
| smaller_bst_root = TreeNode() | ||
| node_in_smaller_bst = smaller_bst_root | ||
| greater_bst_root = TreeNode() | ||
| node_in_greater_bst = greater_bst_root | ||
|
|
||
| while node is not None: | ||
| if node.val <= target: | ||
| node_in_smaller_bst.right = node | ||
| node_in_smaller_bst = node_in_smaller_bst.right | ||
| node = node.right | ||
| node_in_smaller_bst.right = None | ||
| else: | ||
| node_in_greater_bst.left = node | ||
| node_in_greater_bst = node_in_greater_bst.left | ||
| node = node.left | ||
| node_in_greater_bst.left = None | ||
| return [smaller_bst_root.right, greater_bst_root.left] | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. これ再帰を使わなくて済んでとても良いと思いました。 |
||
| ``` | ||
| - https://github.com/Mike0121/LeetCode/pull/16/files | ||
| - https://github.com/hayashi-ay/leetcode/pull/53/files | ||
| - https://github.com/Ryotaro25/leetcode_first60/pull/50/files | ||
| - いくつかPR見たが smaller/greater の組み合わせの人はいない。些細なことだが問題文にある表現を使った方が良いと思う。 | ||
|
|
||
| ## STEP3 | ||
| ### 3回ミスなく書く | ||
| ```python | ||
| class Solution: | ||
| def splitBST(self, root: Optional[TreeNode], target: int) -> List[Optional[TreeNode]]: | ||
| if root is None: | ||
| return [None, None] | ||
|
|
||
| if root.val <= target: | ||
| smaller_root, greater_root = self.splitBST(root.right, target) | ||
| root.right = smaller_root | ||
| return [root, greater_root] | ||
| else: | ||
| smaller_root, greater_root = self.splitBST(root.left, target) | ||
| root.left = greater_root | ||
| return [smaller_root, root] | ||
| ``` | ||
|
|
||
| 2分,2分,2分で3回Accept | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
smarller_root greater_rootとする方が分かりやすいと感じました。