Tree题目汇总
注:将树的题目都总结于此。部分经典的详细解答都会有单独博客分析。
103. Binary Tree Zigzag Level Order Traversal 二叉树的锯齿形层次遍历
107. Binary Tree Level Order Traversal II 二叉树的层次遍历 II
199. Binary Tree Right Side View 二叉树的右视图
226. Invert Binary Tree 翻转二叉树
100. Same Tree 相同的树
101. Symmetric Tree 对称二叉树
110. Balanced Binary Tree 平衡二叉树 ***
1 class Solution:
2 def height(self,root):
3 if not root:return 0
4 left_height = self.height(root.left)+1
5 right_height = self.height(root.right)+1
6 return max(left_height,right_height)
7
8 def isBalanced(self, root: TreeNode) -> bool:
9 if not root:return True
10 if abs(self.height(root.left)-self.height(root.right))>1:
11 return False
12 else:
13 return self.isBalanced(root.left) and self.isBalanced(root.right)
leetcode递归优化后的解法:
https://leetcode.com/problems/balanced-binary-tree/discuss/157645/Python-Tree-tm
222. Count Complete Tree Nodes 完全二叉树的节点个数 ***
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution:
def countNodes(self, root: TreeNode) -> int:
if not root:return 0
res = 0
if not root.left and root.right:
res += self.countNodes(root.right)+1
elif not root.right and root.left:
res += self.countNodes(root.left)+1
else:
res += self.countNodes(root.right)+self.countNodes(root.left)+1
return res
leetcode递归简洁写法:先判断这个完全二叉树是否是满二叉树,是满二叉树则代公式,否则递归调用。
class Solution {
public:
int countNodes(TreeNode* root) {
if(!root) return 0;
int hl=0, hr=0;
TreeNode *l=root, *r=root;
while(l) {hl++;l=l->left;}
while(r) {hr++;r=r->right;}
if(hl==hr) return pow(2,hl)-1;
return 1+countNodes(root->left)+countNodes(root->right);
}
};
112. Path Sum 路径总和 ****
关键在于终止条件的考量!!!
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution:
def hasPathSum(self, root: TreeNode, sum: int) -> bool:
if not root:return False
if not root.left and not root.right:
return root.val==sum
if self.hasPathSum(root.left, sum-root.val):
return True
if self.hasPathSum(root.right,sum-root.val):
return True
return False
404. Sum of Left Leaves 左叶子之和 ***
注意终止条件
class Solution:
def sumOfLeftLeaves(self, root: TreeNode) -> int:
if not root: return 0
res = 0
if root.left and not root.left.left and not root.left.right:
res += root.left.val
res+=self.sumOfLeftLeaves(root.left)
res+=self.sumOfLeftLeaves(root.right)
return res
精简后的代码:
class Solution(object):
def sumOfLeftLeaves(self, root):
if not root: return 0
if root.left and not root.left.left and not root.left.right:
return root.left.val + self.sumOfLeftLeaves(root.right)
return self.sumOfLeftLeaves(root.left) + self.sumOfLeftLeaves(root.right) # isn't leave
257. Binary Tree Paths 二叉树的所有路径 *****
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution:
def binaryTreePaths(self, root: TreeNode) -> List[str]:
if not root:return []
res = []
if not root.left and not root.right:
res.append(str(root.val))
return res
leftstring = self.binaryTreePaths(root.left)
for leftpath in leftstring:
res.append(str(root.val)+'->'+leftpath)
rightstring = self.binaryTreePaths(root.right)
for rightpath in rightstring:
res.append(str(root.val)+'->'+rightpath)
return res
113. Path Sum II 路径总和 II ****
1 class Solution:
2 def pathSum(self, root: TreeNode, sum: int) -> List[List[int]]:
3 if not root: return []
4 res = []
5 if not root.left and not root.right:
6 if root.val==sum:
7 return [[root.val]]
8 else:
9 return []
10 leftpath = self.pathSum(root.left, sum-root.val)
11 for path in leftpath:
12 res.append([root.val]+path)
13 rightpath = self.pathSum(root.right, sum-root.val)
14 for path in rightpath:
15 res.append([root.val]+path)
16 return res
129. Sum Root to Leaf Numbers 求根到叶子节点数字之和
我的思路是按照257题那样先把路径都找到,用str格式保存上,然后再sum。
1 # Definition for a binary tree node.
2 # class TreeNode:
3 # def __init__(self, x):
4 # self.val = x
5 # self.left = None
6 # self.right = None
7
8 class Solution:
9 def helper(self, root):
10 if not root: return []
11 res = []
12 if not root.left and not root.right:
13 return [str(root.val)]
14 leftpath = self.helper(root.left)
15 for node in leftpath:
16 res.append(str(root.val)+node)
17 rightpath = self.helper(root.right)
18 for node in rightpath:
19 res.append(str(root.val)+node)
20 return res
21
22 def sumNumbers(self, root: TreeNode) -> int:
23 if not root:return 0
24 res = self.helper(root)
25 return sum([int(str) for str in res])
26
27
28
然后发现leetcode上有更更更更简洁的方法:
public int sumNumbers(TreeNode root) {
return sum(root, 0);
}
public int sum(TreeNode n, int s){
if (n == null) return 0;
if (n.right == null && n.left == null) return s*10 + n.val;
return sum(n.left, s*10 + n.val) + sum(n.right, s*10 + n.val);
}
98. Validate Binary Search Tree 验证二叉搜索树 ****
以为很简单,实则有深坑!
因为不仅要保证当前节点的左右子树分别小于大于该节点,还要满足全局而言,每个结点的左子树都要比右子树小!
1 # Definition for a binary tree node.
2 # class TreeNode:
3 # def __init__(self, x):
4 # self.val = x
5 # self.left = None
6 # self.right = None
7
8 class Solution:
9 def helper(self, root, lower, upper):
10 if not root:return True
11 if root.val<=lower or root.val>=upper:
12 return False
13 if not self.helper(root.left, lower, root.val):
14 return False
15 if not self.helper(root.right, root.val, upper):
16 return False
17 return True
18
19
20 def isValidBST(self, root: TreeNode) -> bool:
21 return self.helper(root,float('-inf'),float('inf'))
22
653. Two Sum IV - Input is a BST 两数之和IV
way1:因为给定bst,那么中序遍历然后就是有序的了,再双端指针搜索即可。很好地利用了BST的特性!
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution:
def inorder(self,root):
return self.inorder(root.left) +[root.val] +self.inorder(root.right) if root else []
def findTarget(self, root: TreeNode, k: int) -> bool:
sortedres = self.inorder(root)
if len(sortedres)<2:return False
i,j = 0,len(sortedres)-1
while(i<j):
temp = sortedres[i]+sortedres[j]
if temp==k:return True
elif temp<k:i+=1
else:j-=1
return False
way2:利用哈希表来递归检查target-当前节点的值在不在当前列表中,在则返回True,不在则返回False
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution:
def find(self,root,res,k):
if not root:return False
if k-root.val in res:
return True
res.append(root.val)
return self.find(root.left,res,k) or self.find(root.right,res,k)
def findTarget(self, root: TreeNode, k: int) -> bool:
res = []