110. 平衡二叉树 - 力扣(Leetcode)
明确后续遍历,借用昨天最后一题的参考思路,一次AC
# 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 isBalanced(self, root: Optional[TreeNode]) -> bool:
self.bool_balanced = True
def compare_height(cur):
if cur == None:
return 0
left_height = compare_height(cur.left)
right_height = compare_height(cur.right)
if not self.bool_balanced:
return
if abs(left_height-right_height) > 1:
self.bool_balanced = False
return max(left_height, right_height) + 1
compare_height(root)
return self.bool_balanced
下面是GPT4优化后的代码,通过-1来判断是否已经完成非平衡的判断
# 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 isBalanced(self, root: Optional[TreeNode]) -> bool:
return self.check_balance(root) != -1
def check_balance(self, node):
if not node:
return 0
left_height = self.check_balance(node.left)
if left_height == -1:
return -1
right_height = self.check_balance(node.right)
if right_height == -1:
return -1
if abs(left_height - right_height) > 1:
return -1
return max(left_height, right_height) + 1
257. 二叉树的所有路径 - 力扣(Leetcode)
先确定前序遍历,然后用回溯的套路去写,即路径保存在path中,如果遇到了叶子结点则保存path
# 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 binaryTreePaths(self, root: Optional[TreeNode]) -> List[str]:
if not root:
return []
results = []
path = []
def traversal(cur, path):
if not cur:
return
path.append(str(cur.val))
if not cur.left and not cur.right:
results.append("->".join(path))
path.pop()
return
traversal(cur.left, path)
traversal(cur.right, path)
path.pop()
traversal(root, path)
return results
下面是GPT4优化后的代码
# 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 binaryTreePaths(self, root: Optional[TreeNode]) -> List[str]:
if not root:
return []
results = []
def traversal(cur, path):
if not cur:
return
path += str(cur.val)
if not cur.left and not cur.right:
results.append(path)
else:
path += "->"
traversal(cur.left, path)
traversal(cur.right, path)
traversal(root, "")
return results
这个版本的代码将path作为字符串处理,每次递归调用时都会创建一个新的字符串,而不是修改原始列表。这样,我们就不需要在函数返回时调用pop方法。在每个节点,我们检查其是否是叶节点,如果是,我们就将路径添加到结果列表中;否则,我们在路径的末尾添加"->",然后分别遍历左右子树。
404. 左叶子之和 - 力扣(Leetcode)
明确是后序遍历,然后再明确终止条件是空节点和叶子结点,并通过一个left_flag判断是否可以进行累积,代码如下
# 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 sumOfLeftLeaves(self, root: Optional[TreeNode]) -> int:
def traversal(cur, left_flag=False):
if cur == None:
return 0
if cur.left==None and cur.right==None and left_flag:
return cur.val
left_sum = traversal(cur.left, left_flag=True)
right_sum = traversal(cur.right)
return left_sum + right_sum
return traversal(root)
总结
- 今天的第一题和第三题涉及到了值从叶子结点往上累积,关键在于终止条件的判断以及遍历顺序的明确
- 今天第二题涉及到了回溯,这里简单回顾一下回溯的模板以及三部曲
回溯算法模板框架如下:
void backtracking(参数) {
if (终止条件) {
存放结果;
return;
}
for (选择:本层集合中元素(树中节点孩子的数量就是集合的大小)) {
处理节点;
backtracking(路径,选择列表); // 递归
回溯,撤销处理结果;
}
}
回溯法三部曲:
- 递归函数的返回值以及参数
- 回溯函数终止条件
- 单层搜索的过程
附录
代码随想录算法训练营第十七天 | 110. 平衡二叉树、257. 二叉树的所有路径、404. 左叶子之和_小蛙先森的博客-CSDN博客