110.平衡二叉树
题目链接: 110.平衡二叉树 - 力扣(LeetCode)
文章讲解:代码随想录
视频讲解:后序遍历求高度,高度判断是否平衡 | LeetCode:110.平衡二叉树
思路
- 递归:前序遍历的写法
- 可以用迭代法做
递归
class Solution:
def isBalanced(self, root: Optional[TreeNode]) -> bool:
res = True
def recur(root):
nonlocal res
if not root:
return 0
l = recur(root.left)
r = recur(root.right)
if abs(l-r) > 1:
res = False
return max(l,r)+1
recur(root)
return res
递归【另一种写法】
class Solution:
def isBalanced(self, root: Optional[TreeNode]) -> bool:
def high(root):
if not root:
return 0
l = high(root.left)
# -1 表示已经不是平衡二叉树了,否则返回值是以该节点为根节点树的高度
if l == -1:
return -1
r = high(root.right)
if r == -1:
return -1
if abs(l-r) > 1:
return -1
return max(l,r)+1
return high(root) != -1
257. 二叉树的所有路径
题目链接: 257. 二叉树的所有路径 - 力扣(LeetCode)
文章讲解:代码随想录
视频讲解:递归中带着回溯,你感受到了没?| LeetCode:257. 二叉树的所有路径
思路
- 递归:其中用到了回溯的思想
- 迭代
递归
class Solution:
def binaryTreePaths(self, root: Optional[TreeNode]) -> List[str]:
res = []
def recur(root,path):
nonlocal res
if not root:
return
if not root.left and not root.right:
res.append(path)
if root.left:
recur(root.left,path+'->'+str(root.left.val)) # 回溯
if root.right:
recur(root.right,path+'->'+str(root.right.val))
recur(root,str(root.val))
return res
迭代
class Solution:
def binaryTreePaths(self, root: Optional[TreeNode]) -> List[str]:
res = []
stack = [root]
path_stack = [str(root.val)]
while stack:
node = stack.pop()
path = path_stack.pop()
if not node.left and not node.right:
res.append(path)
if node.right:
stack.append(node.right)
path_stack.append(path+'->'+str(node.right.val))
if node.left:
stack.append(node.left)
path_stack.append(path+'->'+str(node.left.val))
return res
404.左叶子之和
题目链接: 404.左叶子之和- 力扣(LeetCode)
文章讲解:代码随想录
视频讲解:二叉树的题目中,总有一些规则让你找不到北 | LeetCode:404.左叶子之和
思路
- 递归【也可以通过节点的父节点来判断其左孩子是不是左叶子】
- 迭代
递归
class Solution:
def sumOfLeftLeaves(self, root: Optional[TreeNode]) -> int:
res = 0
def recur(root,flag):
nonlocal res
if not root:
return
if not root.left and not root.right and flag:
res += root.val
if root.left:
recur(root.left,1)
if root.right:
recur(root.right,0)
recur(root,0)
return res
迭代
class Solution:
def sumOfLeftLeaves(self, root: Optional[TreeNode]) -> int:
res = 0
stack = [(root,0)]
while stack:
node,flag = stack.pop()
if not node.left and not node.right and flag:
res += node.val
if node.right:
stack.append((node.right,0))
if node.left:
stack.append((node.left,1))
return res
222.完全二叉树的节点个数
题目链接: 222.完全二叉树的节点个数- 力扣(LeetCode)
文章讲解:代码随想录
视频讲解:看起来好像做过,一写就错! | LeetCode:111.二叉树的最小深度
思路
- 一般解法,时间复杂度O(n)
- 考虑完全二叉树特性,时间复杂度O(logn*logn)。每次计算满二叉树的时候,计算的其实就是当前树高,即 O(logn),每次递归调用的都是下一层的子树,总共调用了“树的高度”次,即 O(logn),所以时间复杂度为 O(logn) * O(logn)【看的题解】
- 迭代法
递归
class Solution:
def countNodes(self, root: Optional[TreeNode]) -> int:
res = 0
def recur(root):
nonlocal res
if not root:
return
res += 1
if root.left:
recur(root.left)
if root.right:
recur(root.right)
recur(root)
return res
递归【优化时间复杂度】
class Solution:
def countNodes(self, root: Optional[TreeNode]) -> int:
if not root:
return 0
l_height = self.getHeight(root.left)
r_height = self.getHeight(root.right)
if l_height == r_height: # 左子树高度等于右子树,则左子树为满二叉树
return 2**l_height+self.countNodes(root.right)
else: # 左子树高度大于右子树,右子树为满二叉树
return 2**r_height+self.countNodes(root.left)
def getHeight(self,root):
count = 0
while root:
root = root.left
count += 1
return count
迭代
class Solution:
def countNodes(self, root: Optional[TreeNode]) -> int:
if not root:
return 0
stack = [root]
res = 0
while stack:
node = stack.pop()
l_height = self.getHeight(node.left)
r_height = self.getHeight(node.right)
if l_height == r_height: # 左子树高度等于右子树,则左子树为满二叉树
res += 2**l_height
if node.right:
stack.append(node.right)
else: # 左子树高度大于右子树,右子树为满二叉树
res += 2**r_height
if node.left:
stack.append(node.left)
return res
def getHeight(self,root):
count = 0
while root:
root = root.left
count += 1
return count

被折叠的 条评论
为什么被折叠?



