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
28 changes: 28 additions & 0 deletions 112-path-sum/memo.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
## step1で考えたこと

Sumをどうやって渡していくか?関数呼び出しの時に渡すのが良さそう。となるとHelper関数が必要か

self.checkPathSum(root, current_sum)を呼ぶタイミングがどこが適切かがわからない。今の場合だとまだ定義されていないから呼べないよと怒られる。

hasTarget = (current_sum == turgetSum)
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

hasTarget = hasTarget or (current_sum == targetSum)
がやりたかった事ですかね?

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

記号だけでやると|=ですね。


この部分で、三項演算子的なものを使って書きたかったがわからなかった。文法的にあっているかもわからない。

## step1へのフィードバック
内側関数はself不要

leafで判定するとより良い¥

合計を渡す代わりに残りのtargetを減らすやり方の方が賢かった
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

これは、引き継ぐ情報として合計か、合計の補数のようなものを選ぶか、というような考え方に抽象化して考えられます。
引き継ぐ情報の量を減らすためによくある考え方と思います。これの自然な発想法としては、Treeの方を小さくして次に渡すので、合計の方も小さくして次に渡す、といった考え方もあります。


### 参考にした他の人のコード

#### https://github.com/mamo3gr/arai60/pull/24/
再帰の考え方は同じだったが、Queueを使って書くという新しい発想が得られた。
is_leafの議論も面白い。自分も欲しい派

Queueを使ったコードも読みやすい印象を持った。

#### https://github.com/plushn/SWE-Arai60/pull/25/

減法を使って書いていたコード、ほとんど同じ
24 changes: 24 additions & 0 deletions 112-path-sum/step1.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# 動かないコード

# 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:
hasTarget = False
current_sum = 0
self.checkPathSum(root, current_sum)

def checkPathSum(self, node: Optional[TreeNode], current_sum: int):
# leafまで辿り着いた時がnode is None、この時のcurrent_sumがtargetSumと一致しているかをチェック
if node is None:
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

early return してネストを下げたほうが読みやすいかなと思いました。

if node is None:
    hasTarget = (current_sum == targetSum)
    return

current_sum += int(node.val)
self.checkPathSum(node.left, current_sum)
self.checkPathSum(node.right, current_sum)

hasTarget = (current_sum == targetSum)
else:
current_sum += int(node.val)
self.checkPathSum(node.left, current_sum)
self.checkPathSum(node.right, current_sum)

return hasTarget
31 changes: 31 additions & 0 deletions 112-path-sum/step2.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# step1を修正したVersion
# Time Complexity: O(n)
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

この表記を見てしばらく、最悪は容易だが平均がこうなるのを示すのは少し難しいかも?などと色々考えていたのですが、実は木の形を固定した場合にTrue/Falseや見つかる位置などと計算量がほぼ無関係なので、どんな場合を考えてもO(n)ですね。(感想です)

# Space Complexity: O(h)

# 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:
hasTarget = False

def checkPathSum(node: Optional[TreeNode], current_sum: int):
nonlocal hasTarget
if node is None or hasTarget:
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

これらは (node が null) と (ターゲットを発見済み) という別々の条件なので、私だったら2つ別のif文にしますが、ひとまとまりにしてしまう方も多くいらっしゃるとは思います。

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

確かに分けた方がよりそれぞれの目的が明確になりますね

return

current_sum += node.val

if node.left is None and node.right is None:
if current_sum == targetSum:
hasTarget = True
return

checkPathSum(node.left, current_sum)
checkPathSum(node.right, current_sum)
Comment on lines +27 to +28
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

こうすると途中で hasTarget が見つかったとしても、計算が打ち切られずに続きますね。


checkPathSum(root, 0)
return hasTarget
18 changes: 18 additions & 0 deletions 112-path-sum/step3.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# 個人的に落ち着いた回答のコード

# 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 root.val == targetSum

return (self.hasPathSum(root.left, targetSum - root.val) or
self.hasPathSum(root.right, targetSum - root.val))
Comment on lines +17 to +18
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

こちらの or は False が見つかると計算を打ち切りますね。

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

False が見つかると

True が見つかると、ですかね

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

おっとそうです。