110. 平衡二叉树
class Solution:
def isBalanced(self, root: Optional[TreeNode]) -> bool:
if not root: return True
if abs(self.getDepth(root.left) - self.getDepth(root.right)) > 1: return False
return self.isBalanced(root.left) and self.isBalanced(root.right)
def getDepth(self,root):
if not root:
return 0
return 1 + max(self.getDepth(root.left), self.getDepth(root.right))
自己的思路倒是AC了,但是效率有点低。
参考了代码随想录的思路优化代码,可以定义一个getHeight函数用于计算深度,并在计算的过程中给非平衡的二叉树打上标记。换句话说,在求子树高度的时候可以先判断下是否是平衡二叉树,用来剪枝并退出本次递归,效率地解决了问题。
class Solution:
def isBalanced(self, root: Optional[TreeNode]) -> bool:
if not root: return True
return self.getHeight(root) != -1
def getHeight(self,root):
if not root:
return 0
leftHeight = self.getHeight(root.left)
if leftHeight == -1: return -1
rightHeight = self.getHeight(root.right)
if rightHeight == -1: return -1
if abs(leftHeight - rightHeight) > 1: return -1
return max(leftHeight, rightHeight) + 1
257. 二叉树的所有路径
利用递归回溯,记录下所有的路径。
结果是前序遍历的顺序因此使用前序遍历。终止条件就是遇到叶子节点,就把路径加进结果集。递归过程就是前序遍历的递归过程,使用path字符串和result数组记录过程。对于每个栈帧都有一个path,这一层如果不是叶子节点,下一层就给path加上'->'符号递归,直到遇到叶子节点记录后回溯上一栈帧,这时栈帧的path是原本记录好的,继续递归过程。如此循环即可得到所有路径。
class Solution:
def binaryTreePaths(self, root: Optional[TreeNode]) -> List[str]:
result = []
self.getPath(root,'',result)
return result
def getPath(self, node, path, result):
if node:
path += str(node.val)
if not node.left and not node.right:
result.append(path)
else:
path += '->'
if node.left: self.getPath(node.left,path,result)
if node.right: self.getPath(node.right,path,result)
404. 左叶子之和
利用回溯记录左叶子集,如果是从右边回来的,判断一下右边是不是叶子,如果是,剔除结果。
class Solution:
def sumOfLeftLeaves(self, root: Optional[TreeNode]) -> int:
if not root.left and not root.right:
return 0
res = []
self.checkSum(root, res)
return sum(res)
def checkSum(self, root, cnt):
if not root.left and not root.right:
cnt.append(root.val)
if root.left:
self.checkSum(root.left,cnt)
if root.right:
self.checkSum(root.right,cnt)
if not root.right.right and not root.right.left:
cnt.pop()
相对来说,代码随想录的方法更加优雅。遇到叶子节点终止,返回0;回溯后如果发现是左叶子,那就把结果加上。
class Solution:
def sumOfLeftLeaves(self, root: Optional[TreeNode]) -> int:
if not root:
return 0
if not root.left and not root.right:
return 0
l = 0
if root.left and (not root.left.left and not root.left.right):
l = root.left.val
return l + self.sumOfLeftLeaves(root.left) + self.sumOfLeftLeaves(root.right)
今日总结:
回溯发生在递归返回,如果每次都记录递归操作,返回时再操作就是操作回溯。