- 博主简介:努力学习的22级计算机科学与技术本科生一枚
- 博主主页: @是瑶瑶子啦
- 每日一言: 所谓自由,不是随心所欲,而是自我主宰。——康德
二叉树解题的思维模式分两类:
void traverse(TreeNode root) {
if (root == null) {
return;
}
// 前序位置
traverse(root.left);
// 中序位置
traverse(root.right);
// 后序位置
}
前中后序
一道二叉树的题目时的通用思考过程
是否可以通过遍历一遍二叉树得到答案?如果可以,用一个 traverse 函数配合外部变量来实现。
是否可以定义一个递归函数,通过子问题(子树)的答案推导出原问题的答案?如果可以,写出这个递归函数的定义,并充分利用这个函数的返回值。
无论使用哪一种思维模式,你都要明白二叉树的每一个节点需要做什么,需要在什么时候(前中后序)做。
思路:分解成子问题,maxDepth = 1 + 左子树最大高度+右子树最大高度
♀️代码:
public int maxDepth(TreeNode root) {
//临界条件
if(root == null){
return 0;
}
int leftHeight = maxDepth(root.left);//求左子树最大高度
int rightHeight = maxDepth(root.right);//求右子树最大高度
return 1 + Math.max(leftHeight, rightHeight);
}
思路:分解成子问题,递归序列 = add(自身节点)+ add(左子树的递归序列) + add(右子树的递归序列)
♀️代码:
public List<Integer> preorderTraversal(TreeNode root) {
List<Integer> ret = new LinkedList<>();
if(root == null){
return ret;
}
ret.add(root.val);
if(root.left!=null){
List<Integer> leftList = preorderTraversal(root.left);
ret.addAll(leftList);
}
if(root.right!=null){
List<Integer> rightList = preorderTraversal(root.right);
ret.addAll(rightList);
}
return ret;
}
思路:两种模式的结合,首先大的背景是利用maxDepth
进行二叉树的后序遍历+求当前节点左右子树的最大高度.注意需要一个外部变量maxDiameter
来时刻更新最大直径。(这种思路是O(n)的时间复杂度,可以用遍历每个节点+求当前节点的最大直径,思路是一样的,但是复杂度度是O(n2),因为在本方法中在求maxDepth的时候就已经顺带遍历了整个节点!)
♀️代码:
public int maxDiameter;
public int diameterOfBinaryTree(TreeNode root) {
maxDepth(root);
return maxDiameter;
}
public int maxDepth(TreeNode root) {
if(root == null){
return 0;
}
//计算当前节点的左子树最大高度
int leftH = maxDepth(root.left);
//计算当前节点的右子树的最大高度
int rightH = maxDepth(root.right);
maxDiameter = Math.max(maxDiameter,leftH + rightH);//更新maxDiameter
return 1 + Math.max(leftH, rightH);
}
若有不懂的地方,欢迎随时在评论区or私信找瑶瑶子交流讨论
Java岛冒险记【从小白到大佬之路】
LeetCode每日一题–进击大厂
Go语言核心编程
算法