目录
110.平衡二叉树 (优先掌握递归)
再一次涉及到,什么是高度,什么是深度,可以巩固一下。
题目链接/文章讲解/视频讲解:代码随想录
题解思路:
多看卡哥视频,本题也是通过求二叉树的最大高度的后序遍历实现,然后对遍历的时候对每个节点的左右节点高度差的绝对值是否超过1进行了判断
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
class Solution {
public boolean isBalanced(TreeNode root) {
return getHeight(root) != -1; //在getHeight()方法中已经对每个节点的左右节点高度差是否为1进行了判断,所以如果返回的不是-1,就说明已经是平衡二叉树了,此时返回的就是二叉树的最大高度,也是最大深度了
}
public int getHeight(TreeNode node){
if(node == null) return 0;
int leftHeight = getHeight(node.left);
if(leftHeight == -1) return -1;
int rightHeight = getHeight(node.right);
if(rightHeight == -1) return -1;
int result;
if(Math.abs(leftHeight - rightHeight) > 1) return result = -1;
else result = 1 + Math.max(leftHeight,rightHeight);
return result;
}
}
257. 二叉树的所有路径 (优先掌握递归)
这是大家第一次接触到回溯的过程, 我在视频里重点讲解了 本题为什么要有回溯,已经回溯的过程。
如果对回溯 似懂非懂,没关系, 可以先有个印象。
题目链接/文章讲解/视频讲解:代码随想录
题解思路:
先看卡哥视频的大概思路,这里的变量第一遍写的时候有点绕晕了,一定要清楚为什么需要这些容器去装各种元素,本题输出的格式要求每条路径需要按照指定字符串的格式进行输出,所有每条路径拼接的时候可以用StingBuilder进行处理,这种处理API的字符串拼接问题效率高!!!
说完变量的注意,本题最大的坑还是在于理解回溯这个概念,回溯和递归是一一对应的,有一个递归,就要有一个回溯,两个必须紧挨着写的,这样才能没递归完一次,就把存放路径中节点val值集合中的元素弹出一个,但一定是从最后一个在慢慢往前弹出!!!
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
class Solution {
ArrayList<Integer> elementOfPath = new ArrayList<>(); //存放路径中节点val值的集合
ArrayList<String> result = new ArrayList<>(); //将所有字符串路径存放在集合中
public List<String> binaryTreePaths(TreeNode root) {
if(root == null) return null;
return traverse(root);
}
public List<String> traverse(TreeNode node){
elementOfPath.add(node.val); //前序遍历:中
//递归第二步:递归遍历终止条件,在终止条件里面把所有元素按照题目要求输出对应的字符串存储在结果result里面
if(node.left == null && node.right == null){
StringBuilder temp = new StringBuilder(); //将路径中的元素按指定格式拼接字符串,StringBuilder效率高
for(int i = 0; i < elementOfPath.size() - 1; i++){
temp.append(elementOfPath.get(i)).append("->"); //先添加前n - 1个元素
}
//再添加最后一个元素
temp.append(elementOfPath.get(elementOfPath.size() - 1)); //最后一个元素单独处理,因为不需要加 -> 字符串
//将路径添加到结果集合中
result.add(temp.toString());
return result;
}
//递归第三步:处理单层逻辑
if(node.left != null){ //左
traverse(node.left);
elementOfPath.remove(elementOfPath.size() - 1); //回溯
}
if(node.right != null){ //右
traverse(node.right);
elementOfPath.remove(elementOfPath.size() - 1); //回溯
}
return result;
}
}
404.左叶子之和 (优先掌握递归)
其实本题有点文字游戏,搞清楚什么是左叶子,剩下的就是二叉树的基本操作。
题目链接/文章讲解/视频讲解:代码随想录
题解思路:
多看卡哥视频讲解,这里坑主要在于判断是否是左叶子节点取决与该节点是否是叶子节点,同时需要在他的父节点去判断是不是左叶子节点!!!
当能判断该节点是叶子节点之后,但无法判断是不是左叶子节点,让父节点再去重复判断他的左孩子是否为空,并且他左孩子的左右节点是否为空,才能处理该节点的值!!!!只有在一个节点的左孩子是叶子节点时,才能称它为左叶子节点。
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
class Solution {
public int sumOfLeftLeaves(TreeNode root) {
//递归第二步:递归的终止条件
if(root == null) return 0;
if(root.left == null && root.right == null) return 0; //这一步可以不写,写了就是少了一次递归的次数而已
//递归第三步:递归的单层处理逻辑
int leftSum = sumOfLeftLeaves(root.left); //左:这一步返回0只能说明该节点是叶子节点,但无法判断是不是左叶子节点,需要在他的父节点去进行判断并处理该叶子节点的值
//让父节点判断他的左孩子是否为空,并且他左孩子的左右节点是否为空,才能处理该节点的值
if(root.left != null && root.left.left == null && root.left.right == null ) leftSum = root.left.val;
int rightSum = sumOfLeftLeaves(root.right); //右
int result = leftSum + rightSum;//中
return result;
}
}