diff --git a/problems/0112.路径总和.md b/problems/0112.路径总和.md index 51aa1956..0a4f5714 100644 --- a/problems/0112.路径总和.md +++ b/problems/0112.路径总和.md @@ -487,140 +487,191 @@ class Solution { ### 0112.路径总和 -**递归** - +(版本一) 递归 ```python -class solution: - def haspathsum(self, root: treenode, targetsum: int) -> bool: - def isornot(root, targetsum) -> bool: - if (not root.left) and (not root.right) and targetsum == 0: - return true # 遇到叶子节点,并且计数为0 - if (not root.left) and (not root.right): - return false # 遇到叶子节点,计数不为0 - if root.left: - targetsum -= root.left.val # 左节点 - if isornot(root.left, targetsum): return true # 递归,处理左节点 - targetsum += root.left.val # 回溯 - if root.right: - targetsum -= root.right.val # 右节点 - if isornot(root.right, targetsum): return true # 递归,处理右节点 - targetsum += root.right.val # 回溯 - return false - - if root == none: - return false # 别忘记处理空treenode - else: - return isornot(root, targetsum - root.val) +# 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 traversal(self, cur: TreeNode, count: int) -> bool: + if not cur.left and not cur.right and count == 0: # 遇到叶子节点,并且计数为0 + return True + if not cur.left and not cur.right: # 遇到叶子节点直接返回 + return False + + if cur.left: # 左 + count -= cur.left.val + if self.traversal(cur.left, count): # 递归,处理节点 + return True + count += cur.left.val # 回溯,撤销处理结果 -class Solution: # 简洁版 - def hasPathSum(self, root: Optional[TreeNode], targetSum: int) -> bool: - if not root: return False - if root.left==root.right==None and root.val == targetSum: return True - return self.hasPathSum(root.left,targetSum-root.val) or self.hasPathSum(root.right,targetSum-root.val) + if cur.right: # 右 + count -= cur.right.val + if self.traversal(cur.right, count): # 递归,处理节点 + return True + count += cur.right.val # 回溯,撤销处理结果 + + return False + + def hasPathSum(self, root: TreeNode, sum: int) -> bool: + if root is None: + return False + return self.traversal(root, sum - root.val) ``` -**迭代 - 层序遍历** - +(版本二) 递归 + 精简 ```python -class solution: - def haspathsum(self, root: treenode, targetsum: int) -> bool: +# 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: TreeNode, sum: int) -> bool: if not root: - return false - - stack = [] # [(当前节点,路径数值), ...] - stack.append((root, root.val)) - - while stack: - cur_node, path_sum = stack.pop() - - if not cur_node.left and not cur_node.right and path_sum == targetsum: - return true - - if cur_node.right: - stack.append((cur_node.right, path_sum + cur_node.right.val)) - - if cur_node.left: - stack.append((cur_node.left, path_sum + cur_node.left.val)) - - return false + return False + if not root.left and not root.right and sum == root.val: + return True + return self.hasPathSum(root.left, sum - root.val) or self.hasPathSum(root.right, sum - root.val) + ``` +(版本三) 迭代 +```python +# 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: TreeNode, sum: int) -> bool: + if not root: + return False + # 此时栈里要放的是pair<节点指针,路径数值> + st = [(root, root.val)] + while st: + node, path_sum = st.pop() + # 如果该节点是叶子节点了,同时该节点的路径数值等于sum,那么就返回true + if not node.left and not node.right and path_sum == sum: + return True + # 右节点,压进去一个节点的时候,将该节点的路径数值也记录下来 + if node.right: + st.append((node.right, path_sum + node.right.val)) + # 左节点,压进去一个节点的时候,将该节点的路径数值也记录下来 + if node.left: + st.append((node.left, path_sum + node.left.val)) + return False + + + +``` + + ### 0113.路径总和-ii -**递归** - +(版本一) 递归 ```python -class solution: - def pathsum(self, root: treenode, targetsum: int) -> list[list[int]]: +# 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 __init__(self): + self.result = [] + self.path = [] - def traversal(cur_node, remain): - if not cur_node.left and not cur_node.right: - if remain == 0: - result.append(path[:]) - return + def traversal(self, cur, count): + if not cur.left and not cur.right and count == 0: # 遇到了叶子节点且找到了和为sum的路径 + self.result.append(self.path[:]) + return - if cur_node.left: - path.append(cur_node.left.val) - traversal(cur_node.left, remain-cur_node.left.val) - path.pop() + if not cur.left and not cur.right: # 遇到叶子节点而没有找到合适的边,直接返回 + return - if cur_node.right: - path.append(cur_node.right.val) - traversal(cur_node.right, remain-cur_node.right.val) - path.pop() + if cur.left: # 左 (空节点不遍历) + self.path.append(cur.left.val) + count -= cur.left.val + self.traversal(cur.left, count) # 递归 + count += cur.left.val # 回溯 + self.path.pop() # 回溯 - result, path = [], [] + if cur.right: # 右 (空节点不遍历) + self.path.append(cur.right.val) + count -= cur.right.val + self.traversal(cur.right, count) # 递归 + count += cur.right.val # 回溯 + self.path.pop() # 回溯 + + return + + def pathSum(self, root: TreeNode, sum: int) -> List[List[int]]: + self.result.clear() + self.path.clear() if not root: - return [] - path.append(root.val) - traversal(root, targetsum - root.val) - return result + return self.result + self.path.append(root.val) # 把根节点放进路径 + self.traversal(root, sum - root.val) + return self.result ``` -**迭代法,用第二个队列保存目前的总和与路径** - +(版本二) 递归 + 精简 ```python +# 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]]: - if not root: - return [] - que, temp = deque([root]), deque([(root.val, [root.val])]) + def pathSum(self, root: TreeNode, targetSum: int) -> List[List[int]]: + result = [] - while que: - for _ in range(len(que)): - node = que.popleft() - value, path = temp.popleft() - if (not node.left) and (not node.right): - if value == targetSum: - result.append(path) - if node.left: - que.append(node.left) - temp.append((node.left.val+value, path+[node.left.val])) - if node.right: - que.append(node.right) - temp.append((node.right.val+value, path+[node.right.val])) + self.traversal(root, targetSum, [], result) return result + def traversal(self,node, count, path, result): + if not node: + return + path.append(node.val) + count -= node.val + if not node.left and not node.right and count == 0: + result.append(list(path)) + self.traversal(node.left, count, path, result) + self.traversal(node.right, count, path, result) + path.pop() ``` - -**迭代法,前序遍历** - +(版本三) 迭代 ```python +# 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]]: - if not root: return [] - stack, path_stack,result = [[root,root.val]],[[root.val]],[] + def pathSum(self, root: TreeNode, targetSum: int) -> List[List[int]]: + if not root: + return [] + stack = [(root, [root.val])] + res = [] while stack: - cur,cursum = stack.pop() - path = path_stack.pop() - if cur.left==cur.right==None: - if cursum==targetSum: result.append(path) - if cur.right: - stack.append([cur.right,cursum+cur.right.val]) - path_stack.append(path+[cur.right.val]) - if cur.left: - stack.append([cur.left,cursum+cur.left.val]) - path_stack.append(path+[cur.left.val]) - return result + node, path = stack.pop() + if not node.left and not node.right and sum(path) == targetSum: + res.append(path) + if node.right: + stack.append((node.right, path + [node.right.val])) + if node.left: + stack.append((node.left, path + [node.left.val])) + return res + + + ``` ## go