代码随想录|513.找树左下角的值 112. 路径总和 113. 路径总和ii 106.从中序与后序遍历序列构造二叉树

import javax.sound.midi.Track;
import java.util.*;

public class Day14 {
    private static class TreeNode {
        int val;
        TreeNode left;
        TreeNode right;

        public TreeNode(int val) {
            this.val = val;
        }

        public TreeNode(int val, TreeNode left, TreeNode right) {
            this.val = val;
            this.left = left;
            this.right = right;
        }
    }
    //给定一个二叉树的 根节点 root,请找出该二叉树的 最底层 最左边 节点的值。
    //假设二叉树中至少有一个节点。
    public int findBottomLeftValue2(TreeNode root) {
        Queue<TreeNode> queue=new LinkedList<>();
        queue.add(root);
        int result=0;
        while(!queue.isEmpty()){
            int size=queue.size();
            for(int i=0;i<size;i++){//迭代法很简单,只需要记录最左侧的数值就行了,最后返回最后一个数值
                TreeNode node=queue.poll();
                if(i==0) result=node.val;
                if(node.left!=null)
                    queue.add(node.left);
                if(node.right!=null)
                    queue.add(node.right);

            }
        }
        return result;
    }
    int result=0,maxDepth=-1;
    //递归法
    public int findBottomLeftValue(TreeNode root) {
        traversal(root,1);
        return result;
    }
    public void traversal(TreeNode root,int depth) {
        //先左后右顺序遍历,每一个首先深度变大的即为最左侧第一个节点
        if (root.left == null && root.right == null) {
            if (depth > maxDepth) {
                result = root.val;
                maxDepth = depth;
            }
        }
        if (root.left != null) {
            depth++;
            traversal(root.left, depth);
            depth--;
        }
        if(root.right!=null){
            traversal(root.right,depth+1);//简便写法 保持递归出来depth不变
        }
    }
    //给你二叉树的根节点 root 和一个表示目标和的整数 targetSum 。判断该树中是否存在 根节点到叶子节点 的路径,
    // 这条路径上所有节点值相加等于目标和 targetSum 。如果存在,返回 true ;否则,返回 false 。
    //叶子节点 是指没有子节点的节点。
    public boolean hasPathSum(TreeNode root, int targetSum) {
        if (root==null)
            return false;
        return hasPathSumTra(root,targetSum-root.val);//递归时不断减去左右节点数值,
        // 当targetSum=root.val时就是一个需要的路径
    }
    public boolean hasPathSumTra(TreeNode root, int targetSum) {
        if(root==null) return false;
        if(root.left==null&&root.right==null&&targetSum==0)
            return true;
        if(root.left==null&&root.right==null)
            return false;
        if(root.left!=null){
            targetSum-=root.left.val;//回溯
            if(hasPathSumTra(root.left,targetSum))
                return true;
            targetSum+=root.left.val;
        }
        if(root.right!=null){
            targetSum-=root.right.val;
            if(hasPathSumTra(root.right,targetSum))
                return true;
            targetSum+=root.right.val;
        }
        return false;
    }
    public boolean hasPathSum1(TreeNode root, int targetSum) {
        if (root==null)
            return false;
        targetSum-=root.val;
        if(root.left==null&&root.right==null&&targetSum==0)
            return true;
        if(root.left!=null){
            if(hasPathSum1(root.left,targetSum))
                return true;
        }
        if(root.right!=null){
            if(hasPathSum1(root.right,targetSum))
                return true;
        }
        return false;
    }
    //给你二叉树的根节点 root 和一个整数目标和 targetSum ,找出所有 从根节点到叶子节点 路径总和等于给定目标和的路径。
    //
    //叶子节点 是指没有子节点的节点。
    public List<List<Integer>> pathSum(TreeNode root, int targetSum) {
        List<Integer> path=new ArrayList<>();
        List<List<Integer>> result=new ArrayList<>();
        if(root==null)
            return result;
        pathSum(root,targetSum,path,result);
        return result;
    }
    public void pathSum(TreeNode root, int targetSum,List<Integer> path,List<List<Integer>> result) {
        path.add(root.val);
        targetSum-=root.val;
        if(root.left==null&&root.right==null&&targetSum==0){
                result.add(new ArrayList<>(path));
            }
        if (root.left == null && root.right == null) {
            return;
        }
        if(root.left!=null){
            pathSum(root.left,targetSum,path,result);
            path.removeLast();
        }
        if (root.right != null) {
            pathSum(root.right,targetSum,path,result);
            path.removeLast();//回溯
        }
        }
        //给定两个整数数组 inorder 和 postorder ,其中 inorder 是二叉树的中序遍历,
        // postorder 是同一棵树的后序遍历,请你构造并返回这颗 二叉树 。
    public static TreeNode buildTree(int[] inorder, int[] postorder) {
        return buildTreeHelper(inorder,0,inorder.length-1,postorder,0,postorder.length-1);
    }
    public static TreeNode buildTreeHelper(int[] inorder, int inBegin,int inEnd,int[] postorder,int postBegin,int postEnd){
        if(inBegin>inEnd||postBegin>postEnd)
            return null;
        TreeNode root=new TreeNode(postorder[postEnd]);
        int index=inBegin;
        for(;index<=inEnd;index++){
            if(inorder[index]==postorder[postEnd])
                break;
        }//找到左与中的分界线index

        //日志
        System.out.println("inorder");
        for(int i=inBegin;i<=inEnd;i++){
            System.out.print(inorder[i]+" ");
        }
        System.out.println();
        System.out.println("postorder");
        for(int i=postBegin;i<=postEnd;i++){
            System.out.print(postorder[i]+" ");
        }
        System.out.println();

        int leftLength=index-inBegin;//通过找出中序中左子树节点个数,后将后序中的左子树节点找出来
        root.left=buildTreeHelper(inorder,inBegin,index-1,postorder,postBegin,postBegin+leftLength-1);
        root.right=buildTreeHelper(inorder,index+1,inEnd,postorder,postBegin+leftLength,postEnd-1);
        return  root;
    }

    public static void main(String[] args) {
        int[] inorder={9,3,15,20,7};
        int[] postorder={9,15,7,20,3};
        buildTree(inorder,postorder);
    }
}
  • 21
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值