From cc3800fed5513bf7eb758f9ce669f4338e27ec53 Mon Sep 17 00:00:00 2001 From: Manasvi Reddy Date: Thu, 25 Jun 2026 20:05:43 -0400 Subject: [PATCH] Done Trees-3 --- Problem1.py | 37 +++++++++++++++++++++++++++++++++++++ Problem2.py | 33 +++++++++++++++++++++++++++++++++ 2 files changed, 70 insertions(+) create mode 100644 Problem1.py create mode 100644 Problem2.py diff --git a/Problem1.py b/Problem1.py new file mode 100644 index 00000000..903800fd --- /dev/null +++ b/Problem1.py @@ -0,0 +1,37 @@ +# Problem1 (https://leetcode.com/problems/path-sum-ii/) +# Time Complexity: O(n), we visit every node once; building each saved path costs O(h) and there can be up to O(n) such paths in the worst case (skewed tree) +# Space Complexity: O(h), h is the tree height; that's how deep the recursion stack and the shared "path" list go (output space for result not counted) + +# Approach: +# We walk down the tree from root to leaf using recursion, keeping ONE shared list called "path" that holds the values of the current branch we're standing on. +# At every node we do 3 things: add it to the running sum add it to "path"and check if we've hit a leaf with the matching sum (if so, save a COPY of the path). +# Then we go explore the left child completely, then the right child completely. +# Once both children are fully done, we "pop" (remove) the current node from "path" before going back to the parent (this is called backtracking.) +# It undoes our own change so the path is clean and correct for whichever branch gets explored next. + +# 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 pathSum(self, root: Optional[TreeNode], targetSum: int) -> List[List[int]]: + self.result = [] # empty box to collect all winning paths + self.helper(root, targetSum, 0, []) # start walk: sum so far = 0, path so far = empty + return self.result # give back everything we found + + def helper(self, root, targetSum, currSum, path): + if root is None: # no node here (empty spot, ran off the tree) + return # nothing to do, go back to caller + + currSum = root.val + currSum # add this node's value to the running sum + path.append(root.val) # add this node's value to the shared path + + if root.left is None and root.right is None: # this node has no children, it's a leaf + if currSum == targetSum: # check if the sum matches target + self.result.append(list(path)) # save a COPY of path (not the same list!) + + self.helper(root.left, targetSum, currSum, path) # fully explore the left side first + self.helper(root.right, targetSum, currSum, path) # then fully explore the right side + path.pop() # done with this node, remove it before going back(undoes the append from above — keeps path clean for the next branch the parent explores) \ No newline at end of file diff --git a/Problem2.py b/Problem2.py new file mode 100644 index 00000000..ee01f99a --- /dev/null +++ b/Problem2.py @@ -0,0 +1,33 @@ +# Problem2 (https://leetcode.com/problems/symmetric-tree/) +# Time Complexity: O(n),we visit every node in the tree exactly once +# Space Complexity: O(h),recursion stack goes as deep as the tree's height h + +# Logic: +# 1. A tree is symmetric if its left subtree mirrors its right subtree. +# 2. Two nodes mirror each other when their values match AND their outer/inner children mirror. +# 3. We recurse with cross-pairing (left.left with right.right) to compare the mirror directly. + +# 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 isSymmetric(self, root: Optional[TreeNode]) -> bool: + if root is None: # empty tree is symmetric by default + return True # nothing to compare, so return True + return self.helper(root.left, root.right) # ask: do root's two children mirror each other? + + def helper(self, left, right): + if left is None and right is None: # both sides empty at the same spot + return True # they match perfectly, this pair is fine + if left is None or right is None: # exactly one side is empty (other isn't) + return False # one node has nothing to mirror,not symmetric + if left.val != right.val: # both nodes exist but values differ + return False # mismatch found, not symmetric + + # cross-pair the children: outer with outer, inner with inner + return self.helper(left.left, right.right) and self.helper(left.right, right.left) + # outer pair inner pair + #both pairs must mirror (and) for this pair to be symmetric \ No newline at end of file