day18-二叉树part05

 513.找树左下角的值  

本地递归偏难,反而迭代简单属于模板题

        最底层最左边节点的值 先找到树的最深层,只要找到树的最深层无论是左节点还是右节点都是最左边节点的值

class Solution {
    //全局变量
    //深度
    int Max_depth = -1;
    //结果值
    int res = 0;
    public int findBottomLeftValue(TreeNode root) {
        if(root == null){
            return res;
        }
        // res = root.val;
        traversal(root,0);
        return res;
    }

    private void traversal(TreeNode root,int depth){
        if(root.left == null && root.right == null){
            if(depth > Max_depth){
                Max_depth = depth;
                res = root.val;
            }
            return;
        }
        //左
        if(root.left != null){
            depth++;
            traversal(root.left,depth);
            depth--;
        }
        if(root.right != null){
            depth++;
            traversal(root.right,depth);
            depth--;
        }
        return;
    }
}

 112.路径总和

        题目要求找到一条路径即可,递归函数返回值为boolean即可  
class Solution {
    public boolean hasPathSum(TreeNode root, int targetSum) {
        List<Integer> path = new ArrayList<>();
        if(root == null) return false;
        return backTracking(root,path,targetSum);
    }

    //确定递归方法及参数
    public boolean backTracking(TreeNode root,List<Integer> path,int targetSum){
        path.add(root.val);
        //确定递归终止条件
        if(root.left == null && root.right == null){
            int i=0;
            for(int j:path){
                i+=j;
            }
            return i == targetSum;
        }
        //确定递归单层逻辑  
        if(root.left != null){
            if(backTracking(root.left,path,targetSum)){//先往左一直遍历 返回结果
                return true;                           //找到了  targetSum
            }
            path.remove(path.size()-1);                //遍历到最底部 回溯 
        }

        if(root.right != null){
            if(backTracking(root.right,path,targetSum)){//往右遍历 返回结果
                return true;                            //找到了  targetSum
            }
            path.remove(path.size()-1);
        }
        return false;   
    }
}

 113.路径总和ii

class Solution {
    public List<List<Integer>> pathSum(TreeNode root, int targetSum) {
        List<List<Integer>> resList = new ArrayList<>();
        if(root == null){
            return resList;
        }
        List<Integer> path = new ArrayList<>();
        
        tra(resList,targetSum,path,root);
        return resList;
    }

    private void tra(List<List<Integer>> resList,int targetSum,List<Integer> path,TreeNode root){
        path.add(root.val);
        //遇到了叶子节点
        if(root.left == null && root.right == null){
            int sum = 0;
            for(int s : path){
                sum += s;
            }
            if(sum == targetSum){
                resList.add(new ArrayList<>(path));
            }
        }
        //左确认递归单层逻辑 路径回溯
        if(root.left != null){
            tra(resList,targetSum,path,root.left);
            path.remove(path.size() - 1);
        }
        if(root.right != null){
            tra(resList,targetSum,path,root.right);
            path.remove(path.size() - 1);
        }
    }
}

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

   1:如果数组大小为0说明是空节点

    2.如果不为空 取后序数组最后一个元素为根节点元素

    3.找到根节点到中序数组的位置作为切割点

    4.切割中序数组,切成中序左数组和中序右数组

    5.切割后序数组,切成后序左数组与后序右数组

        中序数组中通过根节点切开,左边为根节点左子树节点个数,右边为根节点右子树节点个数

    6.递归处理左区间(中序左数组与后序左数组)与右区间(中序右数组与后序右数组)

        确定好区间定义划分  左闭右开 

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

    private TreeNode buildHelper(int[] inorder,int inorderStart,int inorderEnd,int[] postorder,int postorderStart,int postorderEnd){
        if(postorderStart == postorderEnd) return null;
        int rootVal = postorder[postorderEnd - 1];
        TreeNode root = new TreeNode(rootVal);
        int Midindex;
        for(Midindex = inorderStart;Midindex < inorderEnd;Midindex++){
            if(rootVal == inorder[Midindex]){
                break;
            }
        }
        //左闭右开
        int leftInorderStart = inorderStart;
        int leftInorderEnd = Midindex;
        int rightInorderStart = Midindex+1;
        int rightInorderEnd = inorderEnd;

        int leftPostStart = postorderStart;
        int leftPostEnd = postorderStart + (Midindex - inorderStart);
        int rightPostderStart = postorderStart + (Midindex - inorderStart);
        int rightPostEnd = postorderEnd - 1;
        root.left = buildHelper(inorder,leftInorderStart,leftInorderEnd,postorder,leftPostStart,leftPostEnd);
        root.right = buildHelper(inorder,rightInorderStart,rightInorderEnd,postorder,rightPostderStart,rightPostEnd);
        return root;
    }
}

 105.从前序与中序遍历构造二叉树

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

    private TreeNode buildHelper(int[] inorder,int inorderStart,int inorderEnd,int[] preorder,int preorderStart,int preorderEnd){
        if(preorderStart == preorderEnd) return null;
        int rootVal = preorder[preorderStart];
        TreeNode root = new TreeNode(rootVal);
        int midIndex;
        for(midIndex = inorderStart;midIndex < inorder.length;midIndex++){
            if(inorder[midIndex] == rootVal){
                break;
            }
        }

        int leftInorderStart = inorderStart;
        int leftInorderEnd = midIndex;
        int rightInorderStart = midIndex+1;
        int rightInorderEnd = inorderEnd;

        int leftPreorderStart = preorderStart + 1;
        int leftPreorderEnd = preorderStart + 1 +midIndex - inorderStart;
        int rightPreorderStart = preorderStart + 1 +midIndex - inorderStart;
        int rightPreorderEnd = preorderEnd;
        root.left = buildHelper(inorder,leftInorderStart,leftInorderEnd,preorder,leftPreorderStart,leftPreorderEnd);
        root.right = buildHelper(inorder,rightInorderStart,rightInorderEnd,preorder,rightPreorderStart,rightPreorderEnd);
        return root;
    }
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值