Skip to content
Open
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
75 changes: 75 additions & 0 deletions leetcode/arai60/memo.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
# 112. Path Sum
* 問題: https://leetcode.com/problems/path-sum/
* 言語: Python

## Step1
* 深さ優先探索(DFS)でノードを探索しながら、そのノードまでの和を情報として保持していく
* スタックにノードオブジェクトとそのノードまでの和の組を積んでいく

### 解答(AC)
```py
class Solution:
def hasPathSum(self, root: Optional[TreeNode], targetSum: int) -> bool:
if root is None:
return False

node_and_val = [(root, root.val, root.val)]

Choose a reason for hiding this comment

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

root.valroot からアクセスできるのでスタックに積む必要はないと思います。node_and_path_sum などにするとよさそうですね (最初、2, 3 番目の要素が何を示しているのか戸惑いました)。


while node_and_val:
node, val, sum = node_and_val.pop()

Choose a reason for hiding this comment

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

組み込みの sum を上書きしているので、避けたほうがいいですね。path_sum とするか、やむを得なければ sum_ でしょうか。

https://peps.python.org/pep-0008/#descriptive-naming-styles

single_trailing_underscore_: used by convention to avoid conflicts with Python keyword, e.g. :
tkinter.Toplevel(master, class_='ClassName')

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

Choose a reason for hiding this comment

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

None であるか確認している場合とそうでない場合が混在している点が気になりました。
また、L20 では left を先に書いていて、L23-26 では right を先に書いている点も少し気になりました。

node_and_val.append((node.right, node.right.val, node.right.val + sum))
if node.left:
node_and_val.append((node.left, node.left.val, node.left.val + sum))

return False
```
* 解答時間: 20:03
* 時間計算量: $O(n)$
* 空間計算量: $O(n)$
* `val` は変数に置いたが積まなくて良い
* Step2で再帰バージョンも書いてみる

## Step2
### 他の人のコードを読む
* 典型コメント: https://docs.google.com/document/d/11HV35ADPo9QxJOpJQ24FcZvtvioli770WWdZZDaLOfg/edit?tab=t.0#heading=h.ed3x3pkyeqkp
* https://github.com/rossy0213/leetcode/pull/14
- Java
- 再帰DFS
- 与えられたノード値に直接足し上げているのが気になる
* https://github.com/SuperHotDogCat/coding-interview/pull/37
- Python
- `targetSum` を引き算していき最終的に0になるかどうかで判定
- 再帰DFS
- ```py
class Solution:
def hasPathSum(self, root: Optional[TreeNode], targetSum: int) -> bool:
if root is None:
return False

targetSum = targetSum - root.val
if targetSum == 0 and root.left is None and root.right is None:

Choose a reason for hiding this comment

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

細かいしどちらでもいいですが、

if root.left is None and root.right is None and targetSum == 0:
    ...
if root.left is None and root.right is None:
    if targetSum == 0:
        ...

としたくなりますね。葉であるかどうかが前提条件なおで先にチェックしたいです。

return True
return self.hasPathSum(root.left, targetSum) or self.hasPathSum(root.right, targetSum)
```

# Step3
```py
class Solution:
def hasPathSum(self, root: Optional[TreeNode], targetSum: int) -> bool:
if root is None:
return False

targetSum -= root.val
if targetSum == 0 and root.left is None and root.right is None:
return True

return self.hasPathSum(root.left, targetSum) or self.hasPathSum(root.right, targetSum)
```
* 解答時間:
- 1回目: 1:32
- 2回目: 1:42
- 3回目: 1:39