持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第8天,点击查看活动详情
看完本文你可以解决的问题有:
| 题目 | 题型 |
|---|---|
| 104. 二叉树的最大深度 - 力扣(LeetCode) | 遍历二叉树/分解问题 |
| 543. 二叉树的直径 - 力扣(LeetCode) | 分解问题连带计算答案 |
| 102. 二叉树的层序遍历 - 力扣(LeetCode) | 层序遍历模板 |
| 515. 在每个树行中找最大值 - 力扣(LeetCode) | 层序遍历模板 |
-
思路:
二叉树的问题有两个主体思路:第一种是遍历一遍二叉树得出答案,第二种是通过分解问题计算出答案。
-
理解前中后序:
指的是几个不同的位置。
前序:进入下一个节点之前。
中序:遍历完左子树之后,即将要遍历子树之前。
后序:即将离开当前节点之前。
-
特殊的后序位置:
二叉树的前序位置只能获取父节点传递过来的值,但是后序位置的代码不仅可以获取参数数据,还可以获取子树通过函数返回值传递回来的数据。
-
思考过程:
- 是否可以遍历一遍二叉树得到答案?如果可以,用一个
traverse函数配合外部变量来实现。 - 是否可以定义一个递归函数,通过子问题(子树)的答案推导出原问题的答案?如果可以,写出这个递归函数的定义,并充分利用这个函数的返回值。
- 无论哪一种模式,都需要明白二叉树的每一节点需要做什么,需要在什么时候(前中后序)做?
LeetCode
-
leetcode 104
思路一:通过遍历一遍二叉树得到答案。在刚进入节点时depth++,即将出节点时depth--,并且更新答案。
class Solution {
int depth = 0;
int ans = 0;
public int maxDepth(TreeNode root) {
traverse(root);
return ans;
}
public void traverse(TreeNode root){
if(root == null) return ;
depth++;
if(root.left == null && root.right == null){
ans = Math.max(depth,ans);
}
traverse(root.left);
traverse(root.right);
depth--;
}
}
思路二:通过分解问题的方式得到答案。
class Solution {
//定义函数:返回返回子树的最大深度。
public int maxDepth(TreeNode root) {
if(root == null) return 0;
int leftmax = maxDepth(root.left);
int rightmax = maxDepth(root.right);
int ret = Math.max(leftmax , rightmax) + 1;
return ret;
}
}
-
leetcode 543
分解问题法:定义函数
Depth,返回子树的最大深度。其子树最大直径为Math.max(左子树最大深度+右子树最大深度,直径)。class Solution { int max = 0; public int diameterOfBinaryTree(TreeNode root) { maxDepth(root); return max; } //函数定义:返回每一条子树的最大深度。 public int maxDepth(TreeNode root){ if(root == null) return 0; int leftDepth = maxDepth(root.left); int rightDepth = maxDepth(root.right); int myDepth = leftDepth + rightDepth; max = Math.max(max,myDepth); return 1 + Math.max(leftDepth,rightDepth); } } -
leetcode 102
二叉树的层序遍历。while循环遍历二叉树的行,for循环遍历二叉树的列。
使用队列这一数据结构,先
offerroot节点,之后使用for循环poll一行的节点。利用left和right指针继续offer节点。class Solution { public List<List<Integer>> levelOrder(TreeNode root) { List <List<Integer>> ans = new ArrayList<>(); Queue <TreeNode> q = new LinkedList<>(); if(root == null) return ans; q.offer(root); while(!q.isEmpty()){ List <Integer> ret = new ArrayList<>(); int size = q.size(); for(int i = 0;i< size; i++){ TreeNode cur = q.poll(); ret.add(cur.val); if(cur.left != null){ q.offer(cur.left); } if(cur.right != null){ q.offer(cur.right); } } ans.add(ret); } return ans; } } -
leetcode 515
class Solution { public List<Integer> largestValues(TreeNode root) { List <Integer> ret = new ArrayList<>(); Queue <TreeNode> q = new LinkedList<>(); if(root == null) return ret; q.offer(root); while(!q.isEmpty()){ int size = q.size(); int max = Integer.MIN_VALUE; for(int i =0 ;i<size ; i++){ TreeNode cur = q.poll(); max = Math.max(cur.val,max); if(cur.left != null){ q.offer(cur.left); } if(cur.right != null){ q.offer(cur.right); } } ret.add(max); } return ret; } }\