-
Notifications
You must be signed in to change notification settings - Fork 0
112. Path Sum #27
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?
112. Path Sum #27
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,32 @@ | ||
| ## step1 | ||
| - 幅優先探索みたいなのしたらできそう | ||
| - Node.valにマイナスが入る場合があるので超えたら終わりみたいなことはできなさそう | ||
| - 元のNodeのvalを書き換えるとまずいので、累積の値を管理するものを作る必要がありそう | ||
| - 途中で切ってもいいのかと思っていたが最後の子まで行かないとだめだった | ||
|
|
||
| ## step2 | ||
| - 時間計算量、空間計算量はO(N)だと思う | ||
| - 他の人のコードを見る前に他にやり方がないか考える | ||
| - 取りたくない選択肢だが元のNodeのvalを累積値に書き換えるorTreeNodeに新しいメンバ変数を持たせる | ||
| - やっていることは同じだが、再帰でも同様のことができそう? | ||
| - 一旦書いてみる | ||
| - root is NoneでtargetSum == 0を最終的な条件にしようとしたが、初期条件のrootがNoneでtargetSumが0の場合はFalseにしたいのでhelperを作った | ||
| - 中々うまくかけず、試行錯誤して最終的にChatGPTに聞いてしまった | ||
| - 他の人のコードを見る | ||
| - https://github.com/05ryt31/leetcode/pull/16/files | ||
| - 自分としては少し気をつけたところだが、Trueが見つかった場合に打ち切ってくれるかどうかの観点はあった方が良いと思った | ||
| - https://github.com/mamo3gr/arai60/pull/24 | ||
| - https://github.com/mamo3gr/arai60/pull/24/files#r2678467960 | ||
| - 再帰とキューの比較 | ||
| - 書いている際に条件は確認したがスタックにどのくらい積まれるかは毎回忘れずにmemoでも言及したいと思った | ||
| - `is_leaf`と変数にするのは情報が増えていいと思った | ||
| - https://github.com/naoto-iwase/leetcode/pull/29 | ||
| - `もし葉でtargetSumになるような経路を返却するとしたらどうでしょうか?設問としてはTrue/Falseなのですが、単純にTrue/Falseを得るよりはpathを実際に知るほうが意味があるのかなと思ったので...自分が面接だったら質問しそうです。` | ||
| follow-upの質問があったので考えると、累積を加えて渡すのと同様に通ってきたNodeのlistをtupleに足して管理するようにしそうだが、毎回Listをcopyしないと壊れそうで結構重い処理になりそう | ||
| `そうですね、通ったノードのその時点の和を記録するsetまたは辞書を持つようにし、ゴールの葉からスタートに向かって再びBFS/DFSするのが(空間)計算量が節約できて良さそうですね。さらに、そのようなpathの総数/pathを全部知りたい場合は、1回目の前向きの探索をearly returnなしで完遂し、和の記録も通った回数を辞書で記録しておくのが良さそうに思います。`この解法は思いつかなかったが和を記録したとして親を辿る方法が和が一致する物の中から子を見て一致したら親のNodeと判定しないといけないような気がするので大変だと思った | ||
| - 自分で再帰でも書けそうだと思った部分は進歩だと思うが、やはりすんなり書けないのでもっと練習が必要だと思った | ||
|
|
||
| ## step3 | ||
| - `is_leaf`を使って書くように修正した | ||
| - step1と違いやるべきことが明確に頭の中にあったので5分ほどでかけた | ||
|
|
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,41 @@ | ||
| # | ||
| # @lc app=leetcode id=112 lang=python3 | ||
| # | ||
| # [112] Path Sum | ||
| # | ||
|
|
||
| # @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 | ||
| import collections | ||
|
|
||
|
|
||
| class Solution: | ||
| def hasPathSum(self, root: Optional[TreeNode], targetSum: int) -> bool: | ||
| if root is None: | ||
| return False | ||
| accumulate = root.val | ||
| frontier = collections.deque() | ||
| frontier.append((root, accumulate)) | ||
|
|
||
| while frontier: | ||
| frontier_node, accumulate = frontier.popleft() | ||
| if frontier_node.left is None and frontier_node.right is None: | ||
| if accumulate == targetSum: | ||
| return True | ||
| if frontier_node.left is not None: | ||
| next_accumulate = accumulate + frontier_node.left.val | ||
| frontier.append((frontier_node.left, next_accumulate)) | ||
|
|
||
| if frontier_node.right is not None: | ||
| next_accumulate = accumulate + frontier_node.right.val | ||
| frontier.append((frontier_node.right, next_accumulate)) | ||
|
|
||
| return False | ||
|
|
||
|
|
||
| # @lc code=end | ||
| Original file line number | Diff line number | Diff line change | ||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,27 @@ | ||||||||||||||
| # | ||||||||||||||
| # @lc app=leetcode id=112 lang=python3 | ||||||||||||||
| # | ||||||||||||||
| # [112] Path Sum | ||||||||||||||
| # | ||||||||||||||
|
|
||||||||||||||
| # @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 hasPathSum(self, root: Optional[TreeNode], targetSum: int) -> bool: | ||||||||||||||
| if root is None: | ||||||||||||||
| return False | ||||||||||||||
|
|
||||||||||||||
| if root.left is None and root.right is None: | ||||||||||||||
| return targetSum == root.val | ||||||||||||||
|
|
||||||||||||||
| return self.hasPathSum(root.left, targetSum - root.val) or self.hasPathSum( | ||||||||||||||
| root.right, targetSum - root.val | ||||||||||||||
| ) | ||||||||||||||
|
Comment on lines
+22
to
+24
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. ここ、左右対称な話なのに、フォーマッタに整形させると非対称みたいに見えちゃうんですよね…。
Suggested change
のような選択肢も幅として持っておくといいのかもな、と思いました。 |
||||||||||||||
|
|
||||||||||||||
|
|
||||||||||||||
| # @lc code=end | ||||||||||||||
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
| @@ -0,0 +1,43 @@ | ||||||
| # | ||||||
| # @lc app=leetcode id=112 lang=python3 | ||||||
| # | ||||||
| # [112] Path Sum | ||||||
| # | ||||||
|
|
||||||
| # @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 | ||||||
| import collections | ||||||
|
|
||||||
|
|
||||||
| class Solution: | ||||||
| def hasPathSum(self, root: Optional[TreeNode], targetSum: int) -> bool: | ||||||
| if root is None: | ||||||
| return False | ||||||
| total_val = root.val | ||||||
|
|
||||||
| frontier = collections.deque() | ||||||
| frontier.append((root, total_val)) | ||||||
|
|
||||||
| while frontier: | ||||||
| frontier_node, val = frontier.popleft() | ||||||
|
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.
Suggested change
|
||||||
|
|
||||||
| is_leaf = frontier_node.left is None and frontier_node.right is None | ||||||
|
|
||||||
| if is_leaf and val == targetSum: | ||||||
| return True | ||||||
|
|
||||||
| if frontier_node.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. 冒頭で |
||||||
| frontier.append((frontier_node.left, val + frontier_node.left.val)) | ||||||
|
|
||||||
| if frontier_node.right: | ||||||
| frontier.append((frontier_node.right, val + frontier_node.right.val)) | ||||||
|
|
||||||
| return False | ||||||
|
|
||||||
|
|
||||||
| # @lc code=end | ||||||
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.
動詞の原型を変数名に付けると、関数名のように感じられます。 accumulated はいかがでしょうか?