day18—二叉树part5

文章介绍了如何使用递归和迭代法在二叉树中找到树左下角的值,以及解决路径总和问题。对于路径总和,分别展示了如何判断单路径总和等于目标值,以及找出所有路径总和等于目标值的路径。此外,还讨论了如何根据中序和后序遍历序列构建二叉树的问题。
摘要由CSDN通过智能技术生成

513. 找树左下角的值

思路:

  • 递归法:终止条件:当叶子结点的深度大于我们所记录的深度时,就更新val值,找到第一个深度最大的val值即可。
  • 迭代法:层序遍历,最后一层的第一个值就是想要的树左下角的值。
//递归法
class Solution {
    public int Deep = -1;
    public int val = 0;
    public int findBottomLeftValue(TreeNode root) {
        getLeftValue(root, 0);
        return val;
    }
    private void getLeftValue(TreeNode root, int deep){
        if(root.left==null && root.right==null){
            if(deep > Deep){
                Deep = deep;
                val = root.val;
            }
        }
        if(root.left != null){
            getLeftValue(root.left, deep+1);
        }
        if(root.right != null){
            getLeftValue(root.right, deep+1);
        }
    }
}
//迭代法
class Solution {
    public int findBottomLeftValue(TreeNode root) {
        Queue<TreeNode> queue = new LinkedList();
        if(root != null){queue.offer(root);}
        int size = 0;
        int result = 0;
        while(!queue.isEmpty()){
            size = queue.size();
            result = queue.peek().val;
            while(size > 0){
                TreeNode node = queue.poll();
                if(node.left!=null){queue.offer(node.left);}
                if(node.right!=null){queue.offer(node.right);}
                size--;
            }
        }
        return result;
   

112. 路径总和

思路:递归法遍历的时候加每个节点的值,直到叶子结点查看是否等于taget,回溯的时候再把对应的结点值减去。

class Solution {
    private int sum = 0;
    public boolean isHasPath = false;
    public boolean hasPathSum(TreeNode root, int targetSum) {
        if(root==null){return isHasPath;}
        bianli(root, targetSum);
        return isHasPath;
    }
    private void bianli(TreeNode root, int targetSum){
        sum += root.val;
        if(root.left==null && root.right==null){
            if(sum == targetSum){isHasPath = true;}
        }
        if(root.left != null){
            bianli(root.left, targetSum);
            sum -= root.left.val;
        }
        if(root.right != null){
            bianli(root.right, targetSum);
            sum -= root.right.val;
        }

    }
}

113. 路径总和 II

思路:递归法,用一个双向队列来装遍历过程中变化的数组,遇到叶子结点并且加起来等于target,就把这个数组装到返回的集合ret中。

class Solution {
    List<List<Integer>> ret = new LinkedList<List<Integer>>();
    Deque<Integer> path = new LinkedList<Integer>();

    public List<List<Integer>> pathSum(TreeNode root, int targetSum) {
        dfs(root, targetSum);
        return ret;
    }

    public void dfs(TreeNode root, int targetSum) {
        if (root == null) {
            return;
        }
        path.offerLast(root.val);
        targetSum -= root.val;
        if (root.left == null && root.right == null && targetSum == 0) {
            ret.add(new LinkedList<Integer>(path));
        }
        dfs(root.left, targetSum);
        dfs(root.right, targetSum);
        path.pollLast();
    }
}

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

思路:递归法,以后序数组的最后一个元素为切割点,切割中序数组和后序数组,直到叶子结点再返回,指向root的左右子树。

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 travelsal(inorder, 0, inorder.length, postorder, 0 ,postorder.length);
    }
    private TreeNode travelsal(int[] inorder, int inBegin, int inEnd,
                            int[] postorder, int postBegin, int postEnd){
        if(inBegin>=inEnd || postBegin>=postEnd){
            return null;
        }
        int rootIndex = map.get(postorder[postEnd-1]);
        TreeNode root = new TreeNode(inorder[rootIndex]);
        int lenOfLeft = rootIndex - inBegin;
        root.left = travelsal(inorder, inBegin, rootIndex, postorder, postBegin, postBegin+lenOfLeft);
        root.right = travelsal(inorder, rootIndex+1, inEnd, postorder, postBegin+lenOfLeft, postEnd-1);
        return root;
    }
}

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

思路:跟106差不多。

class Solution {
    Map<Integer, Integer> map;
    public TreeNode buildTree(int[] preorder, int[] inorder) {
        map = new HashMap<>();
        for (int i = 0; i < inorder.length; i++) { // 用map保存中序序列的数值对应位置
            map.put(inorder[i], i);
        }

        return findNode(preorder, 0, preorder.length, inorder,  0, inorder.length);  // 前闭后开
    }

    public TreeNode findNode(int[] preorder, int preBegin, int preEnd, int[] inorder, int inBegin, int inEnd) {
        // 参数里的范围都是前闭后开
        if (preBegin >= preEnd || inBegin >= inEnd) {  // 不满足左闭右开,说明没有元素,返回空树
            return null;
        }
        int rootIndex = map.get(preorder[preBegin]);  // 找到前序遍历的第一个元素在中序遍历中的位置
        TreeNode root = new TreeNode(inorder[rootIndex]);  // 构造结点
        int lenOfLeft = rootIndex - inBegin;  // 保存中序左子树个数,用来确定前序数列的个数
        root.left = findNode(preorder, preBegin + 1, preBegin + lenOfLeft + 1,
                            inorder, inBegin, rootIndex);
        root.right = findNode(preorder, preBegin + lenOfLeft + 1, preEnd,
                            inorder, rootIndex + 1, inEnd);

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值