1、题目1:110-平衡二叉树
类型:简单
平衡二叉树定义为:一个二叉树每个节点 的左右两个子树的高度差的绝对值不超过1。
输入: root = [3,9,20,null,null,15,7] 输出: true
输入: root = [1,2,2,3,3,null,null,4,4] 输出: false
思路:递归法
kotlin
代码解读
复制代码
public class Number110_1 { public boolean isBalanced(TreeNode root) { if(root == null){ return true; } return compareTree(root)==-1?true:false; } // 后序遍历 private int compareTree(TreeNode node) { if(node == null){ return 0; } int leftLen = compareTree(node.left); // 左子树的高度 if(leftLen == -1){ return -1; } int rightLen = compareTree(node.right); if(rightLen ==-1){ return -1; } if(Math.abs(leftLen-rightLen)>1){ return -1; } return 1+Math.max(leftLen,rightLen); } }
2、题目2:257-二叉树的所有路径
类型:简单
给你一个二叉树的根节点 root
,按 任意顺序 ,返回所有从根节点到叶子节点的路径。
叶子节点 是指没有子节点的节点。
输入: root = [1,2,3,null,5] 输出: ["1->2->5","1->3"]
思路:我们使用前序遍历,只有前序遍历,才能让父节点指向孩子节点。
这道题有回溯的。因为我们要把所有路径都记录下来,需要回溯回退一个路径再进入另一个路径。
使用递归:
1、递归函数参数以及返回值。
要传入根结点,记录每一条路径的 path,和存放结果集的result,这里递归不需要返回值;
arduino
代码解读
复制代码
void traversal(TreeNode root, List<Integer> paths, List<String> res)
2、确定递归终止条件
我们的逻辑是处理找到叶子节点,当cur 不为空,且左右孩子都为空的时候,就找到叶子节点/
所以本题的终止条件是:
csharp
代码解读
复制代码
if(cur.left == null && cur.right == null){ // 终止处理逻辑 }
3、确定单层逻辑
因为是前序遍历,需要先处理中间节点,中间节点就是我们要记录路径上的节点,先放进 path 中。
path.push(cur.val)
在递归的时候,因为没有判断 cur 是否为空
回溯和递归是一一对应的,有一个递归,就要有一个回溯。
scss
代码解读
复制代码
public static List<String> binaryTreePaths(TreeNode root) { ArrayList<String> list = new ArrayList<>(); if(root == null){ return list; } ArrayList<Integer> paths = new ArrayList<>(); // 作为结果中的路径 traveList(root,paths,list); return list; } private static void traveList(TreeNode root, ArrayList<Integer> paths, ArrayList<String> list) { // 前序遍历 paths.add(root.val); // 遇到叶子节点 if(root.left == null && root.right ==null){ // 输出 StringBuilder builder = new StringBuilder(); for (Integer path : paths) { builder.append(path).append("->"); } // 删除最后的箭头 builder.delete(builder.length()-2,builder.length()); list.add(builder.toString()); //收集到最后的路径 return; } // 递归和回溯同时进行 if(root.left !=null){ traveList(root.left,paths,list); paths.remove(paths.size()-1); //回溯 } if(root.right !=null){ traveList(root.right,paths,list); paths.remove(paths.size()-1); } }
3、题目3:404-左叶子之和
计算给定二叉树的所有左叶子之和。
示例:
思路:在递归的本层处理逻辑中,判断节点是否为左叶子是无法判断的,必须要通过节点的父节点来判断其左孩子是不是左叶子。
如果该节点的左节点不为空,且该节点的左节点的左节点为空,且该节点的左节点的右节点为空,则找到一个左叶子。
递归三部曲:
1、入参,出参
java
代码解读
复制代码
int getSum(TreeNode root)
2、递归结束条件
kotlin
代码解读
复制代码
if(node == null){ return 0; // 代表没找到 } if(node.left == null && node.right ==null){ return 0; }
3、本轮递归的处理逻辑
ini
代码解读
复制代码
int leftSum = getSum(node.left); if(node.left !=null && node.left.left==null && node.left.right == null){ leftSum =node.left.val;// 找到左节点,返回左节点的值 } int rightSum = getSum(node.right); return leftSum+rightSum;
csharp
代码解读
复制代码
public static int sumOfLeftLeaves(TreeNode root) { if(root == null){ return 0; // 代表没找到 } int leftSum = sumOfLeftLeaves(root.left); // 左递归 if(root.left !=null && root.left.left==null && root.left.right == null){ leftSum = root.left.val; // 找到左节点,返回左节点的值 } int rightSum = sumOfLeftLeaves(root.right); return leftSum+rightSum; }
4、题目4:222-完全二叉树的节点个数
类型:简单
给你一棵 完全二叉树 的根节点 root
,求出该树的节点个数。
完全二叉树 的定义如下:在完全二叉树中,除了最底层节点可能没填满外,其余每层节点数都达到最大值,并且最下面一层的节点都集中在该层最左边的若干位置。若最底层为第 h
层,则该层包含 1~ 2(h)
个节点。
输入: root = [1,2,3,4,5,6] 输出: 6
当成普通二叉树算即可
kotlin
代码解读
复制代码
class Solution { // 通用递归解法 public int countNodes(TreeNode root) { if(root == null) { return 0; } return countNodes(root.left) + countNodes(root.right) + 1; } }