226. 翻转二叉树
前序、后序遍历都可以,中序遍历不可以,因为中序遍历会导致已经翻转的节点再被翻转一次,
中序遍历的顺序是左中右,翻转了左节点的枝后,翻转根节点,再翻转右节点时,右节点其实是已经翻转过的左节点
class Solution {
public TreeNode invertTree(TreeNode root) {
if(root == null || (root.left == null && root.right == null)){
return root;
}
//前序遍历
//TreeNode temp = root.left;
//root.left = root.right;
//root.right = temp;
//if(root.left != null) invertTree(root.left);
//if(root.right != null) invertTree(root.right);
//后序遍历
if(root.left != null) invertTree(root.left);
if(root.right != null) invertTree(root.right);
TreeNode temp = root.left;
root.left = root.right;
root.right = temp;
return root;
}
}
//leetcode submit region end(Prohibit modification and deletion)
}
101. 对称二叉树
递归遍历
使用递归遍历解决该问题,首先要确定使用哪种遍历方式
要同时遍历根节点的左右子树,且左子树遍历顺序为左右中,右子树遍历顺序为右左中
要理清楚在遍历过程中,左右节点是否存在的情况:都不存在,有一个存在,都存在,都不存在是对称的,一个不存在是不对称的,都存在就判断val是否相同
class Solution {
public boolean isSymmetric(TreeNode root) {
return compare(root.left, root.right);
}
/**
* 对称的左右节点比较
* @param left 左节点
* @param right 右节点
* @return
*/
//注意这个方法的参数的左右节点是指要比较是否相同的左右节点,不是一个根节点的左右节点
public boolean compare(TreeNode left, TreeNode right){
if(left == null && right == null){
return true;
}
if((left == null && right != null) || (left != null && right == null)){
return false;
}
if(left.val != right.val){
return false;
}
boolean outer = compare(left.left, right.right);
boolean inner = compare(left.right, right.left);
return outer && inner;
}
}
——————————————————————————————————————————
104. 二叉树的最大深度
二叉树的深度和高度:
- 二叉树节点的深度:指从根节点到该节点的最长简单路径边的条数或者节点数(取决于深度从0开始还是从1开始)
- 二叉树节点的高度:指从该节点到叶子节点的最长简单路径边的条数或者节点数(取决于高度从0开始还是从1开始)
本题使用后续遍历求高度,根节点的高度就是该二叉树的最大深度。每一次递归都求其左右子树的最大深度,最后遍历根节点,这是就能获得左右子树的最大深度,取其中最大值 + 1(加上根节点)即为最大深度
class Solution {
int maxNum = 0;
public int maxDepth(TreeNode root) {
//后序遍历
//if(root == null){
// return 0;
//}
//int leftMaxDepth = maxDepth(root.left);
//int rightMaxDepth = maxDepth(root.right);
//return Math.max(leftMaxDepth + 1, rightMaxDepth + 1);
//也可以使用前序遍历求最大深度
maxHeight(root,1);
return maxNum;
}
private void maxHeight(TreeNode root, int nowHHeight){
if(root == null){
return;
}
maxNum = Math.max(maxNum, nowHHeight);
maxHeight(root.left, nowHHeight + 1);//左
maxHeight(root.right, nowHHeight + 1);//右
}
}
//leetcode submit region end(Prohibit modification and deletion)
}
——————————————————————————————————————————
111. 二叉树的最小深度
第一个想法是参考104 二叉树的最大深度 的后序遍历的方法,先求出左右子树的最小深度,加一即为当前节点的最小深度
但这个想法是错的,其实先求出左右子树的最小深度的思路没问题,主要是递归中止条件的判断,104是当前节点为null,即最大深度为0,
但是本题如果按照这个逻辑,左右孩子其中一个节点为null的节点的最小深度为1,其实应该为2的。
这里想到一个补救方法,当左右子树其中有一个的深度为0时,取另一个不为0的子树深度 + 1当作当前节点的最小深度 。
使用前序遍历也可以求出,只在找到叶子节点时才判定更改最小深度
class Solution {
int minNum = Integer.MAX_VALUE;
public int minDepth(TreeNode root) {
//后序遍历
//if(root == null){
// return 0;
//}
//int leftMinDepth = minDepth(root.left);
//int rightMinDepth = minDepth(root.right);
//if(leftMinDepth == 0 || rightMinDepth == 0){
// return Math.max(leftMinDepth, rightMinDepth) + 1;
//}
//return Math.min(leftMinDepth, rightMinDepth) + 1;
if(root == null){
return 0;
}
min(root, 1);
return minNum;
}
//使用前序遍历是否更清晰?
private void min(TreeNode root, int nowDepth){
if(root.left == null && root.right == null){
minNum = Math.min(minNum,nowDepth);//找到叶子节点才判定更改最小深度
}
if(root.left != null) min(root.left, nowDepth + 1);
if(root.right != null) min(root.right, nowDepth + 1);
}
}
——————————————————————————————————————————