leetcode刷穿二叉树

Posted 深林无鹿

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了leetcode刷穿二叉树相关的知识,希望对你有一定的参考价值。

这里有leetcode题集分类整理!!!

  • leetcode 513. 找树左下角的值
  • leetcode 112. 路径总和
  • leetcode 113. 路径总和 II
  • leetcode 106. 从中序与后序遍历序列构造二叉树
  • leetcode 105. 从前序与中序遍历序列构造二叉树
    1、找树左下角的值
    题目难度:中等
    题目描述:
    在这里插入图片描述
    解题思路一(bfs):

找二叉树最左下角的值,我们要明确一点是最左边的值,还是最底层的最左边的值,根据题意,我们得知,最后的结果应该是最底层的最左边的值,根据题意我们第一个思路:
使用bfs求得 最后一行元素, 然后拿最后一个元素就可以了
代码如下:(广度优先的板子加个ans记录队列最前面的值就好)

class Solution {
    public int findBottomLeftValue(TreeNode root) {
        int ans = 0;
        if (root == null) return ans;
        Deque<TreeNode> queue = new LinkedList<>();
        queue.offer(root);
        while (!queue.isEmpty()) {
            int size = queue.size();
            // 记录每一层第一个元素
            ans = queue.peek().val;
            for (int i = 0; i < size; i ++) {
                TreeNode node = queue.poll();
                if (node.left != null) {
                    queue.offer(node.left);
                }
                if (node.right != null) {
                    queue.offer(node.right);
                }
            }
        }
        return ans;
    }
}

解题思路二(dfs):

若要求得最左下角的值,只需要在dfs的时候时刻根据最大深度更新最大值即可。

class Solution {
    private int ans = 0;
    private int maxDepth = -1;
    public int findBottomLeftValue(TreeNode root) {
        preOrderTraversal(root, 0);
        return ans;
    }

    public void preOrderTraversal(TreeNode root, int curDepth) {
        if (root == null) return ;
        if (curDepth > maxDepth) {
            ans = root.val;
            maxDepth = curDepth;
        }
        preOrderTraversal(root.left, curDepth + 1);
        preOrderTraversal(root.right, curDepth + 1);
    }
}

在这里插入图片描述
2、路经总和
题目难度:简单
题目描述:
在这里插入图片描述
在这里插入图片描述
解题思路:(dfs 回溯)

由于没有看提示,盲目提交,犯了两个错误

  • 没有看清targetSum的范围 导致 剪支失败
  • 边界特殊数据返回值 与 后台测试数据冲突
    如下代码中的注释:
class Solution {
    public boolean hasPathSum(TreeNode root, int targetSum) {
        if (root == null) return false;
        // 下面这条会导致空集合 + 0 返回true
        // if (root == null) return targetSum == 0;
        // 下面这条会导致负数targetSum直接返回false;
        // if (targetSum < 0) return false;
        if (root.left == null && root.right == null) {
            return targetSum == root.val;
        }
        return hasPathSum(root.left, targetSum - root.val) || hasPathSum (root.right, targetSum - root.val);
    }
}

3、路径总和 II
题目难度:中等
题目描述:
在这里插入图片描述
解题思路:

在记录的时候遇到满足条件的情况就录入结果集。
在每轮dfs完毕后要将队列中最后一个元素剔除。

class Solution {
    private List<List<Integer>> res = new ArrayList<>();
    private Deque<Integer> path = new LinkedList<>();
    public List<List<Integer>> pathSum(TreeNode root, int targetSum) {
        List<Integer> path = new ArrayList<>();
        dfs(root, targetSum);
        return res;
    }

    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) {
            res.add(new LinkedList<Integer>(path));
        }
        dfs(root.left, targetSum);
        dfs (root.right, targetSum);
        path.pollLast();
    }
}

4、从中序与后序遍历序列构造二叉树
题目难度:中等
题目描述:

在这里插入图片描述

解题思路:
在这里插入图片描述
在这里插入图片描述
变量名解释:

is: inorder traversal start
ie: inorder traversal end
ri: rootindex
ps: postorder traversal start
pe: postorder traversal end

树的还原过程:
在这里插入图片描述

优秀题解原文链接

class Solution {
    private HashMap<Integer, Integer> memo = new HashMap<>();
    int[] post;
    public TreeNode buildTree(int[] inorder, int[] postorder) {
        post = postorder;
        for (int i = 0; i < inorder.length; i ++) {
            memo.put(inorder[i], i);
        }
        TreeNode root = buildTree(0, inorder.length - 1, 0, postorder.length - 1);
        return root;
    }

    public TreeNode buildTree(int is, int ie, int ps, int pe) {
        if (ie < is || pe < ps) return null;

        int root = post[pe];
        int ri = memo.get(root);

        TreeNode node = new TreeNode(root);
        node.left = buildTree(is, ri - 1, ps, ps + ri - is - 1);
        node.right = buildTree(ri + 1, ie, ps + ri - is, pe - 1);
        return node;
    }
}

5、从前序与中序遍历序列构造二叉树
题目难度:中等
题目描述:
在这里插入图片描述
解题思路:

参看第四题图解
根据前序遍历为 中左右对顺序,只需要令root = preorder[ps] 即可
剩下index的截取可以自己脑补图像写出

class Solution {
    int[] preorder;
    HashMap<Integer, Integer> memo = new HashMap<>();
    public TreeNode buildTree(int[] preorder, int[] inorder) {
        this.preorder = preorder;
        for (int i = 0; i < inorder.length; i ++) {
            memo.put(inorder[i], i);
        }
        return buildTree(0, preorder.length - 1, 0, inorder.length - 1);
    }

    public TreeNode buildTree(int ps, int pe, int is, int ie) {
        if (ps > pe || is > ie) return null;
        int root = preorder[ps];
        int ri = memo.get(root);
        TreeNode node = new TreeNode(root);
        node.left = buildTree(ps + 1, ps + ri - is, is, ri - 1);
        node.right = buildTree(ps + ri - is + 1, pe, ri + 1, ie);
        return node;
    }
}

以上是关于leetcode刷穿二叉树的主要内容,如果未能解决你的问题,请参考以下文章

leetcode刷穿二叉树

leetcode刷穿二叉树

leetcode刷穿二叉树

leetcode刷穿二叉树(完结)

leetcode刷穿二叉树(完结)

leetcode刷穿二叉树(完结)