From 022ee4f0b76c3d6bb9514f949e85df2ecb625234 Mon Sep 17 00:00:00 2001 From: nittoco <166355467+nittoco@users.noreply.github.com> Date: Tue, 30 Jul 2024 16:11:48 +0900 Subject: [PATCH 1/2] 112. Path Sum https://leetcode.com/problems/path-sum/description/ Given the root of a binary tree and an integer targetSum, return true if the tree has a root-to-leaf path such that adding up all the values along the path equals targetSum. A leaf is a node with no children. --- 112. Path Sum.md | 96 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 96 insertions(+) create mode 100644 112. Path Sum.md diff --git a/112. Path Sum.md b/112. Path Sum.md new file mode 100644 index 0000000..0edcd06 --- /dev/null +++ b/112. Path Sum.md @@ -0,0 +1,96 @@ +### Step1 + +- 本当は部下に仕事を任せてreturnしてもらう実装が好きだが、値の候補がたくさんreturnされてしまうのがどうかと思い、backtrackingで書いた +- nonlocalでもいいが、mutableなリストで書いた +- 最初、子供がいるかは判定せずに、if not node: の時にtargetと照合しようとして失敗。片方しか子供がいない時にも判定されてしまう。 +- このbacktrackingのアルゴリズムをリファクタリンぎしたやつをStep2の最後に記載 + +```python + +class Solution: + def hasPathSum(self, root: Optional[TreeNode], targetSum: int) -> bool: + def search_target_sum(sum_so_far, node: Optional[TreeNode]): + sum_so_far += node.val + if not (node.left or node.right): + if sum_so_far == targetSum: + has_target[0] = True + if node.left: + search_target_sum(sum_so_far, node.left) + if node.right: + search_target_sum(sum_so_far, node.right) + sum_so_far -= node.val + + if not root: + return False + has_target = [False] + search_target_sum(0, root) + return has_target[0] +``` + +### Step2 +- [参考] + - (https://github.com/TORUS0818/leetcode/pull/27/files) + - (https://github.com/kazukiii/leetcode/pull/26/files) +- 再帰をするなら、単にFalse, Trueを返す関数を作ればよかった。(なぜか変にsumを全部返さなきゃとか思ってしまった) +- 下でこれをさらにリファクタしてます + +```python + +class Solution: + def hasPathSum(self, root: Optional[TreeNode], targetSum: int) -> bool: + def search_target_sum(sum_so_far, node: Optional[TreeNode]): + sum_so_far += node.val + if not (node.left or node.right): + return sum_so_far == targetSum + if node.left and search_target_sum(sum_so_far, node.left): + return True + if node.right and search_target_sum(sum_so_far, node.right): + return True + return False + + if not root: + return False + return search_target_sum(0, root) +``` + +- if not node: でreturn Falseすればいいのか〜 + - なんか、葉であるのとnodeがそもそもないのを両方関数内で判定すると言う発想がなかった + - こう言うのは最後のないところまで探索するのがいいね + +```python + +class Solution: + def hasPathSum(self, root: Optional[TreeNode], targetSum: int) -> bool: + def search_target_sum(sum_so_far, node: Optional[TreeNode]): + if not node: + return False + sum_so_far += node.val + if not (node.left or node.right): + return sum_so_far == targetSum + return search_target_sum(sum_so_far, node.left) or search_target_sum(sum_so_far, node.right) + + return search_target_sum(0, root) +``` + +- 手でやるならbacktrackingのように足し引きしながら計算する気がするので、Step1を綺麗にしたやつを書いてみる + - [True]みたいに要素数1のリストを持たせるのも微妙かと思い、path_sumsをsetで持たせることにした + - returnに()をつけるか迷った(つけないと分かりにくいか、不要か) + +```python + +class Solution: + def hasPathSum(self, root: Optional[TreeNode], targetSum: int) -> bool: + def caluculate_path_sums(sum_so_far, node: Optional[TreeNode], path_sums: set): + if not node: + return + sum_so_far += node.val + if not node.left and not node.right: + path_sums.add(sum_so_far) + caluculate_path_sums(sum_so_far, node.left, path_sums) + caluculate_path_sums(sum_so_far, node.right, path_sums) + sum_so_far -= node.val + + path_sums = set() + caluculate_path_sums(0, root, path_sums) + return (targetSum in path_sums) +``` From d5de116509e5f4a79866567fbcf6a315300cedf0 Mon Sep 17 00:00:00 2001 From: nittoco <166355467+nittoco@users.noreply.github.com> Date: Thu, 1 Aug 2024 22:39:08 +0900 Subject: [PATCH 2/2] =?UTF-8?q?112.=20Path=20Sum=E3=80=80=E3=83=AC?= =?UTF-8?q?=E3=83=93=E3=83=A5=E3=83=BC=E3=82=92=E5=8F=8D=E6=98=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- 112. Path Sum.md | 43 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/112. Path Sum.md b/112. Path Sum.md index 0edcd06..8bdc15a 100644 --- a/112. Path Sum.md +++ b/112. Path Sum.md @@ -94,3 +94,46 @@ class Solution: caluculate_path_sums(0, root, path_sums) return (targetSum in path_sums) ``` + +## Step3(レビュー反映復習) +```python + +class Solution: + def hasPathSum(self, root: Optional[TreeNode], targetSum: int) -> bool: + def search_target_sum(sum_so_far, node: Optional[TreeNode]): + nonlocal has_target + if not node: + return + sum_so_far += node.val + if not node.left and not node.right: + if sum_so_far == targetSum: + has_target = True + return + search_target_sum(sum_so_far, node.left) + search_target_sum(sum_so_far, node.right) + + has_target = False + search_target_sum(0, root) + return has_target +``` + +- こうは書かないけど一応 + +```python +python +class Solution: + def hasPathSum(self, root: Optional[TreeNode], targetSum: int) -> bool: + def calculate_path_sums(node, sum_so_far): + if not node: + return + sum_so_far += node.val + if not node.left and not node.right: + path_sums.add(sum_so_far) + calculate_path_sums(node.left, sum_so_far) + calculate_path_sums(node.right, sum_so_far) + + path_sums = set() + calculate_path_sums(root, 0) + return targetSum in path_sums + +```