Day17 第六章 二叉树part05

一. 学习文章及资料

  • 513.找树左下角的值
  • 112.路径总和 
  • 106.从中序与后序遍历序列构造二叉树 

二. 学习内容

1. 找树左下角的值

(1) 解题思路:

在树的最后一行找到最左边的值。

如何确认是最后一行?

深度最大的叶子节点一定是最后一行。

如何找最左边的呢?

使用前序遍历(当然中序,后序都可以因为本题没有中间节点的处理逻辑,只要左优先就行),保证优先左边搜索,然后记录深度最大的叶子节点,此时就是树的最后一行最左边的值。

递归法:

  1. 确定递归函数的参数和返回值:
    参数必须有要遍历的树的根节点,还有就是一个int型的变量用来记录最长深度。 这里就不需要返回值了,所以递归函数的返回类型为void。
    本题还需要类里的两个全局变量,maxDepth用来记录最大深度,result记录最大深度最左节点的数值
  2. 确定终止条件:
    当遇到叶子节点的时候,就需要统计一下最大的深度了,所以需要遇到叶子节点来更新最大深度
  3. 确定单层递归的逻辑:
    在找最大深度的时候,递归的过程中依然要使用回溯
class Solution {
    int maxDepth=Integer.MIN_VALUE;
    int result=0;
    void traversal(TreeNode root,int depth){
        if(root.left==null&&root.right==null){
            if(depth>maxDepth){
                maxDepth=depth;
                result=root.val;
            }
            return;
        }
        if(root.left!=null){
            depth++;
            traversal(root.left,depth);
            depth--;
        }
        if(root.right!=null){
            depth++;
            traversal(root.right,depth);
            depth--;
        }
        return;
    }
    public int findBottomLeftValue(TreeNode root) {
        traversal(root,0);
        return result;
    }
}

迭代法(层序遍历):

class Solution {
    public int findBottomLeftValue(TreeNode root) {
        Queue queue=new LinkedList<>();
        int result=0;
        if(root!=null) queue.offer(root);
        while(!queue.isEmpty()){
            int size=queue.size();
            for(int i=0;i

2. 路径总和 

(1) 递归问题:

递归函数什么时候要有返回值,什么时候没有返回值,特别是有的时候递归函数返回类型为boolean类型 ?

  • 如果需要搜索整棵二叉树且不用处理递归返回值,递归函数就不要返回值。
  • 如果需要搜索整棵二叉树且需要处理递归返回值,递归函数就需要返回值。
  • 如果要搜索其中一条符合条件的路径,那么递归一定需要返回值,因为遇到符合条件的路径了就要及时返回。(本题的情况)

递归法:

  1. 确定递归函数的参数和返回类型
    参数:需要二叉树的根节点,还需要一个计数器,这个计数器用来计算二叉树的一条边之和是否正好是目标和,计数器为int型。
  2. 确定终止条件
    首先计数器如何统计这一条路径的和呢?用递减,让计数器count初始为目标和,然后每次减去遍历路径节点上的数值。如果最后count == 0,同时到了叶子节点的话,说明找到了目标和。如果遍历到了叶子节点,count不为0,就是没找到。
  3. 确定单层递归的逻辑
    因为终止条件是判断叶子节点,所以递归的过程中就不要让空节点进入递归了。
    递归函数是有返回值的,如果递归函数返回true,说明找到了合适的路径,应该立刻返回。
class Solution {
    public boolean hasPathSum(TreeNode root, int targetSum) {
        if(root==null) return false;
        targetSum-=root.val;
        // 叶子结点
        if(root.left==null&&root.right==null) return targetSum==0;
        if(root.left!=null){
           boolean left=hasPathSum(root.left,targetSum);
           if(left) return true;   //已找到
        }
        if(root.right!=null){
            boolean right=hasPathSum(root.right,targetSum);
            if(right) return true; //已找到
        }
        return false;
    }
}

3. 从中序与后序遍历序列构造二叉树 

(1) 解题步骤:

  1. 如果数组大小为零的话,说明是空节点了。
  2. 如果不为空,那么取后序数组最后一个元素作为节点元素。
  3. 找到后序数组最后一个元素在中序数组的位置,作为切割点
  4. 切割中序数组,切成中序左数组和中序右数组 (顺序别搞反了,一定是先切中序数组)
  5. 切割后序数组,切成后序左数组和后序右数组
  6. 递归处理左区间和右区间
class Solution {
    public TreeNode buildTree(int[] inorder, int[] postorder) {
        if(postorder.length==0) return null;

        int rootValue=postorder[postorder.length-1];
        TreeNode root=new TreeNode(rootValue);

        if(postorder.length==1) return root;

        int delimiterIndex;
        for(delimiterIndex=0;delimiterIndex

同理 从前序与中序遍历序列构造二叉树

class Solution {
    public TreeNode buildTree(int[] preorder, int[] inorder) {
        if(preorder.length==0) return null;

        int rootValue=preorder[0];
        TreeNode root=new TreeNode(rootValue);
        
        if(preorder.length==1) return root;

        int delimiterIndex;
        for(delimiterIndex=0;delimiterIndex

(2) 一点扩展:

前序和中序可以唯一确定一棵二叉树。

后序和中序可以唯一确定一棵二叉树。

那么前序和后序可不可以唯一确定一棵二叉树呢?

前序和后序不能唯一确定一棵二叉树!因为没有中序遍历无法确定左右部分,也就是无法分割

你可能感兴趣的:(算法)