Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions arai60/path_sum/phase1.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
class Solution:
def hasPathSum(self, root: Optional[TreeNode], targetSum: int) -> bool:
if not root:
return False

targetSum = targetSum - root.val # update targetSum
if targetSum == 0 and not root.right and not root.left:
return True
return self.hasPathSum(root.right, targetSum) | self.hasPathSum(root.left, targetSum)
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

再帰できる回数の上限を考えた上での実装判断ですかね?そうであれば良いと思います

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

問題文にbinary tree, The number of nodes in the tree is in the range [0, 5000].とあったので木の高さは深くてもlog_2(n)ぐらいだろうと思いましたが, 片方に偏る場合もテストケースとして考えられるので再帰回数増やすかやめた方が良さそうですね...

33 changes: 33 additions & 0 deletions arai60/path_sum/phase2.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
"""
Reference:
fhiyo: https://github.com/fhiyo/leetcode/pull/27/files
sakupan102: https://github.com/sakupan102/arai60-practice/pull/26#discussion_r1593805972

・phase1ではtargetSumを更新して0かどうかを判断していたが, 葉だったらtargetSum == root.valかどうかを返してそれ以外はrest = targetSum - root.valとして処理する方が好みだったので書き換える。
・|演算子よりかはor演算子の方が良いか(|はビット演算子, orの方がboolを扱う時の方では馴染みがありそう...?)
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

補足程度に...。
https://docs.python.org/3.12/library/stdtypes.html#boolean-type-bool

For logical operations, use the boolean operators and, or and not. When applying the bitwise operators &, |, ^ to two booleans, they return a bool equivalent to the logical operations “and”, “or”, “xor”. However, the logical operators and, or and != should be preferred over &, | and ^.

とあるので、 "and", "or", "!=" を使う方が好まれるようです

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ありがとうございます

"""

class Solution:
def hasPathSum(self, root: Optional[TreeNode], targetSum: int) -> bool:
if not root:
return False

if not root.right and not root.left:
return targetSum == root.val
rest = targetSum - root.val # update targetSum
return self.hasPathSum(root.right, rest) or self.hasPathSum(root.left, rest)

class Solution:
def hasPathSum(self, root: Optional[TreeNode], targetSum: int) -> bool:
stack = [(root, targetSum)]
while stack:
node, current_sum = stack.pop()
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

好みかもですが、dequeにしてpopleftにした方が、BFSにするのであれば素直な処理の順番になると思いました。

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

今回はDFSのつもりで書いたのですがどうでしょうか....?

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

これはDFSです。

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

すみません、きちんとDFSになっています。
BFSであればあとのappendの順番も変更する必要がありますね。再帰の解法がDFSだったので、BFSの解法を載せているのかなと勝手に思ってしまいました。
的外れなレビューをして混乱を招いてしまい、大変申し訳御座いません。

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

スタックならDFS、キューならBFSになります。

if not node:
continue
if not node.right and not node.left and node.val == current_sum:
return True

rest = current_sum - node.val
Comment on lines +27 to +30
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

これ、引き算先にしちゃって、

if not node.left and not node.right:
    return rest == 0

のほうが素直ではないでしょうか。

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

その訂正の仕方だと, まだ探索しきっていない葉のうち, rest == 0となるものがあるのにrest != 0となるものが先に判定に来ると間違った回答を出してしまう気がします。rest = current_sum - node.valを先にしましょうというのは, その通りかもしれません。

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

この場合は、node.left, node.right がともに None なのでいいんじゃないですか。

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

スクリーンショット 2024-07-05 1 35 09

直し方はこのスクショの通りで大丈夫でしょうか...?

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

再帰ではなく、iterativeな解法なので、ここでreturnすると最終結果になってしまいます。
正しくはこんな感じでしょうか。

if not node.left and not node.right and rest == 0:
    return True

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

おっと、とんでもない勘違いをしていましたね。なぜか再帰な気持ちになっていました。

stack.append((node.right, rest))
stack.append((node.left, rest))
return False
8 changes: 8 additions & 0 deletions arai60/path_sum/phase3.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
class Solution:
def hasPathSum(self, root: Optional[TreeNode], targetSum: int) -> bool:
if not root:
return False
if not root.right and not root.left:
return targetSum == root.val
rest = targetSum - root.val
return self.hasPathSum(root.left, rest) or self.hasPathSum(root.right, rest)