代码随想录Day15 二叉树 LeetCodeT513 找树左下角的值 T112路径总和 T106 从中序和后序遍历构造二叉树

简介: 代码随想录Day15 二叉树 LeetCodeT513 找树左下角的值 T112路径总和 T106 从中序和后序遍历构造二叉树

以上思路来自于:代码随想录 (programmercarl.com)

LeetCode T513 找树左下角的值

题目思路:

本题思路:这题我们使用递归法和迭代法解决问题

注意:左下角的值不一定就是一直向左遍历的叶子结点的值,首先可以确定是最后一行的第一个叶子结点的值,也就是最大深度的叶子结点的值

定义最大深度Deep变量,返回值result

1.递归法

前序遍历为例

1.1 确定递归的返回值和参数类型

我们这里不需要返回值,传入参数是节点和深度

void travelsal(TreeNode node,int deep)

1.2 确定终止条件

这里我们遇到一次叶子结点就更新一次最大深度,并记录下该节点的val

if(node.left == null && node.right == null)
        {
            if(deep>Deep)
            {
                Deep = deep;
                result = node.val;
            }
        }

1.3 实现一次递归

if(node.left != null)
        {
            travelsal(node.left,deep+1);
        }
        if(node.right != null)
        {
            travelsal(node.right,deep+1);
        }

2.迭代法

思路:使用层序遍历,找到最后一行,记录下最左边节点的数值

1.使用队列结构,队列不为空就继续,先加入根节点,接着我们用一个临时节点记录一下正在遍历的节点,方便取值,使用for循环,遍历每一层,记录下每一层第一个值,如果不是叶子节点就继续入队,详细思路可以看 层序遍历章节

代码解析:

public int findBottomLeftValue(TreeNode root) {
        //迭代法
       int result = 0;
       Queue<TreeNode> que = new LinkedList<>();
       que.offer(root);
       while(!que.isEmpty())
       {
           int size = que.size();
           for(int i = 0;i<size;i++)
           {
               TreeNode tmp = que.poll();
               if(i == 0)
               {
                   result = tmp.val;
               }
               if(tmp.left != null)
               {
                  que.offer(tmp.left);
               }
               if(tmp.right != null)
               {
                   que.offer(tmp.right);
               }
           }
       }
       return result;
    }
}

题目代码:

class Solution {
    int Deep = -1;
    int result = 0;
    public int findBottomLeftValue(TreeNode root) {
        result = root.val;
        travelsal(root,0);
        return result;
    }
    void travelsal(TreeNode node,int deep)
    {
        if(node == null)
        {
            return;
        } 
        if(node.left == null && node.right == null)
        {
            if(deep>Deep)
            {
                Deep = deep;
                result = node.val;
            }
        }
        if(node.left != null)
        {
            travelsal(node.left,deep+1);
        }
        if(node.right != null)
        {
            travelsal(node.right,deep+1);
        }
    }
}

LeetCode T112 路径总和

题目链接:112. 路径总和 - 力扣(LeetCode)

题目思路:

思路其实很简单,我们只需要遍历二叉树在叶子节点的时候判断即可,但是还是有很多细节需要注意,我们分一下几步操作,判断节点是否为空,减去该节点的值,判断叶子结点的值,下面就是递归的过程

1.判断头结点

if(root == null)
        {
            return false;
        }

2.叶子节点

//叶子结点
        if(root.left == null && root.right == null)
        {
            return targetSum == 0;
        }

3.递归过程

//递归逻辑
        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;
            }
        }

注:我们这里用目标值一直往下减,如果到叶子节点发现值减到0就说明成功了,注意回溯的过程这里省略了.

题目代码:

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;
    }  
}

T106 从中序和后序遍历构造二叉树

题目链接:106. 从中序与后序遍历序列构造二叉树 - 力扣(LeetCode)

题目思路:

这题思路较为简单,代码较长,我们举一个例子

我们首先根据后序的左右中来切割中序数组,就能知道9是左子树,15 20 7是右子树

然后根据右子树判断中节点是20,20的左节点是15右节点是7,我们就能唯一确定一个二叉树

这里我们分为以下几步处理

1.创建一个map来便于查找

2.将inorder的数据保存到map中 (key是数值,value是下标)

3.接着我们使用递归来实现

4.确定参数和返回值

public TreeNode findNode(int[] inorder, int inBegin, int inEnd, int[] postorder, int postBegin, int postEnd)

5.终止条件(注意这里切分区间要统一,使用闭区间还是左开右闭区间)

if (inBegin >= inEnd || postBegin >= postEnd) {  // 不满足左闭右开,说明没有元素,返回空树
            return null;
        }

6.单次递归

int rootIndex = map.get(postorder[postEnd - 1]);  // 找到后序遍历的最后一个元素在中序遍历中的位置
        TreeNode root = new TreeNode(inorder[rootIndex]);  // 构造结点
        int lenOfLeft = rootIndex - inBegin;  // 保存中序左子树个数,用来确定后序数列的个数
        root.left = findNode(inorder, inBegin, rootIndex,
                            postorder, postBegin, postBegin + lenOfLeft);
        root.right = findNode(inorder, rootIndex + 1, inEnd,
                            postorder, postBegin + lenOfLeft, postEnd - 1);

题目代码:

class Solution {
    Map<Integer,Integer> map;
    public TreeNode buildTree(int[] inorder, int[] postorder) {
        map = new HashMap<>();
        for(int i = 0;i<inorder.length;i++)
        {
            map.put(inorder[i],i);
        }
        return FindOrder(inorder,0,inorder.length,postorder,0,postorder.length);
    }
    public TreeNode FindOrder(int[] inOrder,int inBegin,int inEnd,int[] postOrder,int postBegin,int postEnd)
    {
        //结束条件,这里我使用左闭右开写
        if(inBegin>=inEnd || postBegin>=postEnd)
        {
            return null;
        }
        //找到后序在中序的位置
        int index = map.get(postOrder[postEnd - 1]);
        //构造节点
        TreeNode root = new TreeNode(inOrder[index]);
        //保存中序左子树的个数,用来确定后序的区间
        int lenOfLeft = index - inBegin;
        root.left = FindOrder(inOrder,inBegin,index,postOrder,postBegin,postBegin+lenOfLeft);
        root.right = FindOrder(inOrder,index+1,inEnd,postOrder,postBegin+lenOfLeft,postEnd-1);
        return root;
    }
}
相关文章
【剑指offer】-二叉树中和为某一值的路径-24/67
【剑指offer】-二叉树中和为某一值的路径-24/67
|
算法
代码随想录Day14 LeetCodeT110平衡二叉树 T257二叉树的所有路径 T404 左叶子之和
代码随想录Day14 LeetCodeT110平衡二叉树 T257二叉树的所有路径 T404 左叶子之和
35 0
|
算法
代码随想录算法训练营第十八天 | 力扣 513. 找树左下角的值、112. 路径总和、113. 路径总和 II、106. 从中序与后序遍历序列构造二叉树、105. 从前序与中序遍历序列构造二叉树
代码随想录算法训练营第十八天 | 力扣 513. 找树左下角的值、112. 路径总和、113. 路径总和 II、106. 从中序与后序遍历序列构造二叉树、105. 从前序与中序遍历序列构造二叉树
57 0
|
存储 算法
算法训练Day18|● 513.找树左下角的值● 112. 路径总和 113.路径总和ii● 106.从中序与后序遍历序列构造二叉树 105.从前序与中序遍历序列构造二叉树
算法训练Day18|● 513.找树左下角的值● 112. 路径总和 113.路径总和ii● 106.从中序与后序遍历序列构造二叉树 105.从前序与中序遍历序列构造二叉树
|
存储 算法 Java
代码随想录训练营day18| 513.找树左下角的值 112. 路径总和 106.从中序与后序遍历序列构造二叉树...
代码随想录训练营day18| 513.找树左下角的值 112. 路径总和 106.从中序与后序遍历序列构造二叉树...
剑指offer_二叉树---二叉树中和为某一值的路径
剑指offer_二叉树---二叉树中和为某一值的路径
81 0
剑指offer 35. 二叉树中和为某一值的路径
剑指offer 35. 二叉树中和为某一值的路径
57 0
每日三题-验证二叉搜索树、二叉树的直径、把二叉搜索树转换为累加树
每日三题-验证二叉搜索树、二叉树的直径、把二叉搜索树转换为累加树验证二叉搜索树验证二叉搜索树v
63 2
每日三题-验证二叉搜索树、二叉树的直径、把二叉搜索树转换为累加树
|
存储 前端开发 程序员
二叉树中和为某一值的路径
二叉树中和为某一值的路径
二叉树中和为某一值的路径