110.平衡二叉树
LeetCode - The World's Leading Online Programming Learning Platform
思路:本题要求判断一棵树是否是平衡二叉树, 平衡二叉树的定义是对于所有node左subtree 的高度 - 右subtree 高度的绝对值不能大于1. 求一个node 的高度可以用递归法, 1 + max(height(node.left), height(node.right))。 这里因为需要对所有的node判断, 要求所有node 的高度, 包含了大量的重复遍历, 因此我这里通过一次遍历, 把node 的高度赋值给node的 val. 这样可以简化复杂度。
难点: 这里搞懂代码实现的时候, leaf的高度是 0 还是1 。
class Solution:
def get_height(self, cur_node: Optional[TreeNode]) -> int:
if not cur_node:
return -1
height = 1 + max(self.get_height(cur_node.left), self.get_height(cur_node.right))
cur_node.val = height
return height
def isBalanced(self, root: Optional[TreeNode]) -> bool:
max_height = self.get_height(root)
if not root:
return True
stack = deque([root])
while stack:
cur_node = stack.pop()
l_height, r_height = -1, -1
if cur_node.right:
r_height = cur_node.right.val
stack.append(cur_node.right)
if cur_node.left:
l_height = cur_node.left.val
stack.append(cur_node.left)
if abs(l_height - r_height) > 1:
return False
return True
257. 二叉树的所有路径
LeetCode - The World's Leading Online Programming Learning Platform
思路: 这里不仅要遍历二叉树, 还要回溯走过的路径。 如果使用迭代法, 可以把路径作为参数传递下去, 如果使用递归法, 可以设计 栈里面元素的结构为(node, path_to_node)。 明白这一点, 剩下的就是遍历二叉树, 如果碰到leaf, 就把leaf 的路径放入ans 列表中。
难点: 回溯
递归法:
class Solution:
def binaryTreePaths(self, root: Optional[TreeNode]) -> List[str]:
st = deque()
st.append((root, str(root.val)))
ans = []
while st:
cur_node, cur_path = st.pop()
if cur_node:
if cur_node.right: st.append((cur_node.right, cur_path+f'->{cur_node.right.val}'))
if cur_node.left: st.append((cur_node.left, cur_path+f'->{cur_node.left.val}'))
st.append((cur_node, cur_path))
st.append((None, None))
else:
cur_node, cur_path = st.pop()
if not (cur_node.left or cur_node.right):
ans.append(cur_path)
return ans
迭代法:
class Solution:
def binaryTreePaths(self, root: Optional[TreeNode]) -> List[str]:
paths = []
def get_cur_path(cur_node, prev_path) -> None:
cur_path = prev_path + f'->{cur_node.val}'
if not (cur_node.left or cur_node.right):
paths.append(cur_path[2:])
return
if cur_node.left: get_cur_path(cur_node.left, cur_path)
if cur_node.right: get_cur_path(cur_node.right, cur_path)
get_cur_path(root, '')
return paths
404.左叶子之和
https://leetcode.com/problems/sum-of-left-leaves/description/
思路: 和上一题类似, 遍历的时候使用多一个int 值的flag记录当前的node 是parent 的左node还是右node。 这里如果是左node, 可以标记1, 右node 可以用 flag=0. 这样处理, 如果碰到leaf, 可以直接用 sum = sum + val * flag, 提高代码可读性。
class Solution:
def sumOfLeftLeaves(self, root: Optional[TreeNode]) -> int:
# 使用顺序遍历,栈中的数据结构为set, set[0]是node, set[1]记录是否是左边的node
st = deque()
st.append((root, 0))
sums = 0
while st:
cur_node, is_left = st.pop()
if not (cur_node.left or cur_node.right):
sums += cur_node.val * is_left
if cur_node.left:
st.append((cur_node.left, 1))
if cur_node.right:
st.append((cur_node.right, 0))
return sums