-
Notifications
You must be signed in to change notification settings - Fork 0
776. Split BST #49
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
Open
ryoooooory
wants to merge
1
commit into
main
Choose a base branch
from
task/776
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
776. Split BST #49
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,50 @@ | ||
| /* | ||
| ・概要 | ||
| 自力解法。 | ||
| テストケースの洗い出しが足りず、そもそも求められているものと違うことに気づくが、解法がわからずACできず。 | ||
| 15分くらい | ||
|
|
||
| */ | ||
|
|
||
| import javax.swing.tree.TreeNode; | ||
|
|
||
| public class solution1_1 { | ||
| public TreeNode[] splitBST(TreeNode root, int target) { | ||
| if (root.val == target) { | ||
| return new TreeNode[] {root, null}; | ||
| } | ||
| return new TreeNode[] {getTargetTreeAndChangeSubTree(root, target), root}; | ||
| } | ||
|
|
||
| private TreeNode getTargetTreeAndChangeSubTree(TreeNode current, int target) { | ||
| if (current == null) { | ||
| return null; | ||
| } | ||
| if (target < current.val) { | ||
| if (current.left == null) { | ||
| return null; | ||
| } | ||
| if (current.left.val == target) { | ||
| TreeNode subTree = current.left; | ||
| current.left = current.left.right; | ||
| subTree.right = null; | ||
| return subTree; | ||
| } else { | ||
| return getTargetTreeAndChangeSubTree(current.left, target); | ||
| } | ||
| } else { | ||
| if (current.right == null) { | ||
| return null; | ||
| } | ||
| if (current.right.val == target) { | ||
| TreeNode subTree = current.right; | ||
|
|
||
| current.right = current.right.left; | ||
| subTree.left = null; | ||
| return subTree; | ||
| } else { | ||
| return getTargetTreeAndChangeSubTree(current.right, target); | ||
| } | ||
| } | ||
| } | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,45 @@ | ||
| /* | ||
| ・概要 | ||
| LeetCodeの解説や他の人の解法をみた。 | ||
| https://github.com/Ryotaro25/leetcode_first60/pull/50/files | ||
|
|
||
| ・解法 | ||
| この問題では、元の木構造を保ちながら、target以下の値だけの木と、targetより大きい値の木に分けるという内容である。 | ||
| solution1_1で直感的にできそうだが、 | ||
| 8 | ||
| 3 9 | ||
| 4 | ||
| 5 | ||
| みたいな木でtargetが5のときに対応できない。 | ||
| ということで根から各々木を降りながらみていく。各再帰で返す値は、その時点でのtarget以下の木とtargetより大きいだけの木である。 | ||
| 木の値がtarget以下であれば、左の部分木はBSTなのですべてその木の値以下なので構造を変える必要がない。逆に右の部分木はまだTarget以下の木がある可能性があるので、再帰で見る必要がある。 | ||
| 再帰でかえされる二つの木の内、target以下の木については、現在の値よりは大きいはず(元々自身の右の部分木の一部なので)なので、右の部分木にする。 | ||
| 木の値がtargetより大きい値であれば、先ほどと同様の動きで左の部分木をみていく。 | ||
|
|
||
| ・計算量 | ||
| O(h): 木の深さ | ||
|
|
||
| ・所感 | ||
| 簡単なテストケースのみで問題の本質を誤認してしまった。またBSTの内容を理解していれば、単純に親との関係を見るだけではダメなことは気付けだはず。 | ||
| 本質的な原因はテストケースの洗い出しが適当だったこと、LeetCodeのテストサンプルだけを鵜呑みにしたことが原因なので、 | ||
| https://github.com/goto-untrapped/Arai60/pull/54/files | ||
| にあるとおり、シンプルケース→もうすこし難しいケース→エッジケースの流れの洗い出しを必ずするようにする(まだ仕事での取り組み方とLeetCodeでの問題のやり方を分離していてよくない。) | ||
|
|
||
| */ | ||
|
|
||
| public class solution2_1 { | ||
| public TreeNode[] splitBST(TreeNode root, int target) { | ||
| if (root == null) { | ||
| return new TreeNode[2]; | ||
| } | ||
| if (target < root.val) { | ||
| TreeNode[] small = splitBST(root.left, target); | ||
| root.left = leftSubTree[1]; | ||
| return new TreeNode[] {leftSubTree[0], root}; | ||
| } else { | ||
| TreeNode[] rightSubTree = splitBST(root.right, target); | ||
| root.right = rightSubTree[0]; | ||
| return new TreeNode[] {root, rightSubTree[1]}; | ||
| } | ||
| } | ||
| } | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,42 @@ | ||
| /* | ||
| ・概要 | ||
| LeetCodeの解説や他の人の解法を見たもの | ||
| https://github.com/Ryotaro25/leetcode_first60/pull/50/files#diff-776c4af48e8dabf508f652032b95d33f3ef8308547e1fdd2dc55e447d6bc1af8R26 | ||
|
|
||
| 自分の言葉で頭を整理する。 | ||
|
|
||
| ・解法 | ||
| 再帰を使わずに繰り返し処理で実装したもの | ||
| 考え方は再帰と一緒だが、再帰のbottomupと違って、根から順々に処理していくので、上から順に木を繋げていく。 | ||
| 繰り返し処理の部分は、再帰と一緒で現在の木の値がtarget以下かどうかで処理を分ける。 | ||
| 現在見ている木の値がtarget以下の時は、target以下の木に繋げていく。現在のtarget以下の木の現在みているものをXとする。ここで気になるのはXの左右のどちらに繋ぐかということだが、 | ||
| Xの左の部分木は必ずtarget以下となっていて、そもそも探索する必要がないので探索してXに繋ぐ可能性があるのはXの右の部分木に含まれる木であり、つまりXより大きい値なのでXの右に繋ぐしかない。 | ||
| 上記である通り、次に探索するのは現在の木の右の部分木となる。 | ||
| またこのときtarget以下の木についても現在の木に更新し、かつその木の右の部分木はtargetより大きい可能性もあるのでnullにする。 | ||
| 現在見ている木の値がtarget以上の時も、上記と同様に行なっていく | ||
| */ | ||
|
|
||
| public class solution2_2 { | ||
| public TreeNode[] splitBST(TreeNode root, int target) { | ||
| TreeNode current = root; | ||
| TreeNode smallDummy = new TreeNode(0); | ||
| TreeNode largeDummy = new TreeNode(0); | ||
| TreeNode smallTail = smallDummy; | ||
| TreeNode largeTail = largeDummy; | ||
|
|
||
| while (current != null) { | ||
| if (current.val <= target) { | ||
| smallTail.right = current; | ||
| smallTail = current; | ||
| current = current.right; | ||
| smallTail.right = null; | ||
| } else { | ||
| largeTail.left = current; | ||
| largeTail = current; | ||
| current = current.left; | ||
| largeTail.left = null; | ||
| } | ||
| } | ||
| return new TreeNode[] {smallDummy.right, largeDummy.left}; | ||
| } | ||
| } |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
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.
紙と鉛筆で絵を書く、くらいですかねえ……。