代码随想录算法训练营DAY18|二叉树part5

513.找树左下角的值

在这里插入图片描述
本题很明显用层次遍历是最简单的:

class Solution {
    public int findBottomLeftValue(TreeNode root) {
        List<List<Integer>> res=Order(root);//获得层次遍历序列
        //取出最下面一层
        List<Integer> lastlayer=res.get(res.size()-1);
        int leftvalue=lastlayer.get(0);
        return leftvalue;

    }

        //得到二叉树层序遍历的数组
    public List<List<Integer>> Order(TreeNode root){
        if(root==null){
            return null;
        }
        List<List<Integer>> resList=new ArrayList<>();
        Queue<TreeNode> q=new LinkedList<>();
        q.offer(root);
        while(!q.isEmpty()){
            int len=q.size();
            List<Integer> list=new ArrayList<>();
            while(len>0){
                TreeNode node=q.poll();//从队列取出头元素
                list.add(node.val);
                if(node.left!=null){
                   q.offer(node.left);
                 }
                if(node.right!=null){
                     q.offer(node.right);
                 }
                 len--;
            }
            resList.add(list);
        }
        return resList;
    }
}

112.路径总和

在这里插入图片描述
本题应该是一个深度优先遍历的过程,然后在最后的叶子结点回溯一下。
在这里插入图片描述


/**
 * 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 hasPathSum(TreeNode root, int targetSum) {
        if(root==null){
            return false;
        }
        //如果是叶子结点,判断,target值从根节点一路减下来,和当前值是否相等
        if(root.left==null&&root.right==null){
           return targetSum == root.val;
        }
        if(root.left!=null){
        	//往左子树找
            boolean left=hasPathSum(root.left, targetSum-root.val);
            if (left) {
                return true;//找到
            }
        
        }
        if(root.right!=null){
            //往右子树找
             boolean right=hasPathSum(root.right, targetSum-root.val);
           if (right) {
                return true;//找到
            }
        }
        return false;
    }
}

113.路径总和2

给定一个二叉树和一个目标和,找到所有从根节点到叶子节点路径总和等于给定目标和的路径。

说明: 叶子节点是指没有子节点的节点。

示例: 给定如下二叉树,以及目标和 sum = 22,

在这里插入图片描述

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

正常手写构造二叉树的过程
中序:9 3 15 20 7
后序:9 15 7 20 3
后序遍历的最后一个结点就是根节点3。在中序遍历里找到这个结点划分左右,3的右边就是右子树,左边就是左子树,本题里中序里的3的左边只有9,3的右边有15,20,7,这就是组成右子树的结点。
再从后序:15 7 20中得出,20就是右子树的根结点。中序15 20 7,那么15就是20的左孩子,7就是20的右孩子。

在这里插入图片描述

思路:递归

  • 判断数组是否为空。
  • 取出postorder的最后一个作为结点元素
  • 切割中序,切成左和右。
  • 切割后序,切成后序左和右。
  • 递归处理左区间,又区间。

重要的点,就是中序数组大小一定是和后序数组的大小相同的

在这里插入图片描述
在这里插入图片描述
确定切割的标准:遵循左闭右开原则 :[ )
分析:单层的切割逻辑

切左边:

  • rootIndex:当前的中序里根的位置
    在这里插入图片描述
    这边切一刀,实际上就是rootIndex-inBegin=1-0=1,左子树的个数是1。
    根据这个去切后序,后序的左也要和中序的个数保持一致。
    在这里插入图片描述
    leftpostend:后序左子树的终止,postBegin+lenOfLeft.
    新的中序和后序就产生了。
    切右边:
  • 中序的begin就是rootindex下一个下标,inEnd还是inEnd,不变。
  • 后序的rightBegin=postBegin+lenOfLeft;
  • 后序的eng就是原来的end-1(减去作为root的那个结点)
    在这里插入图片描述
 //切割后序的右子树
        int rightpostBegin=postBegin+lenOfLeft;
        int rightpostEnd=postEnd-1;
        newroot.right=findNode(inorder,rootIndex+1,inEnd,postorder,rightpostBegin,rightpostEnd);//建立右子树
   //根据rootIndex切割中序序列
        int lenOfLeft=rootIndex-inBegin;//左子树应该有的结点个数。
        //根据中序左子树去切后序的左子树
        int leftpostEnd=postBegin+lenOfLeft;
        newroot.left=findNode(inorder,inBegin,rootIndex,postorder,postBegin,leftpostEnd);//建立左子树
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 findNode(inorder,0,inorder.length,postorder,0,postorder.length);

    }

    /**
     *
     * @param inorder 中序遍历序列
     * @param inBegin 中序起始
     * @param inEnd 中序截至
     * @param postorder 后序序列
     * @param postBegin 后起
     * @param postEnd 后止
     * @return
     */
    public TreeNode findNode(int[] inorder,int inBegin,int inEnd,int[] postorder,int postBegin,int postEnd){
        if(inBegin>=inEnd||postBegin>=postEnd){
            return null;
        }
        //找到后序遍历的最后一个结点,作为当前的根节点
        int root=postorder[postEnd-1];//后序遍历最后一个元素
        //找到这个根节点在中序中的位置。
        int rootIndex=map.get(root);
        //新建结点
        TreeNode newroot=new TreeNode(inorder[rootIndex]);
        //根据rootIndex切割中序序列
        int lenOfLeft=rootIndex-inBegin;//左子树应该有的结点个数。
        //根据中序左子树去切后序的左子树
        int leftpostEnd=postBegin+lenOfLeft;
        newroot.left=findNode(inorder,inBegin,rootIndex,postorder,postBegin,leftpostEnd);//建立左子树
        //切割后序的右子树
        int rightpostBegin=postBegin+lenOfLeft;
        int rightpostEnd=postEnd-1;
        newroot.right=findNode(inorder,rootIndex+1,inEnd,postorder,rightpostBegin,rightpostEnd);//建立右子树
        return newroot;
    }
}
  • 7
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值