代码跟学Day18【代码随想录】

第六章 二叉树 part05

大纲

● 513.找树左下角的值
● 112. 路径总和 113.路径总和ii
● 106.从中序与后序遍历序列构造二叉树 105.从前序与中序遍历序列构造二叉树

leetcode 513 找树左下角的值

思路

  • 递归法 注意回溯思想的运用
    • 传递的参数depth+1 隐藏回溯
  • 迭代法
    • 直接使用队列层次遍历寻找深度最深的第一个叶子结点即可

代码

class Solution {
    int res = 0;
    int maxDepth = -1;
    public int findBottomLeftValue(TreeNode root) {
        traverse(root, 0);
        return res;
    }

    public void traverse(TreeNode node, int depth) {
        if (node == null) return;
        if (node.left == null && node.right == null)
            if (depth > maxDepth) {
                res = node.val;
                maxDepth = depth;
            }
        if (node.left != null) traverse(node.left, depth + 1);
        if (node.right != null) traverse(node.right, depth + 1);
    }
}
class Solution {
    public int findBottomLeftValue(TreeNode root) {
        int res = root.val;
        Queue<TreeNode> queue = new LinkedList<>();
        queue.offer(root);
        while (!queue.isEmpty()) {
            int size = queue.size();
            for (int i = 0; i < size; i++) {
                TreeNode node = queue.poll();
                if (i == 0) res = node.val;
                if (node.left != null) queue.offer(node.left);
                if (node.right != null) queue.offer(node.right);
            }
        }
        return res;
    }
}

leetcode 112 路径总和

思路

  • 递归注意使用目标值递减的方法回溯递归
  • 迭代法
    • 注意可使用两栈分别保存结点和当前值
    • 也可以使用一栈保存两值 注意值读取顺序
    • 使用一栈会节省30%的内存空间

代码

class Solution {
    public boolean hasPathSum(TreeNode root, int targetSum) {
        if (root == null) return false;
        if (root.left == null && root.right == null && targetSum == root.val) return true;
        return hasPathSum(root.left, targetSum - root.val) || hasPathSum(root.right, targetSum - root.val);
    }
}

class Solution {
    public boolean hasPathSum(TreeNode root, int targetSum) {
        if (root == null) return false;
        Stack<TreeNode> s1 = new Stack<>();
        Stack<Integer> s2 = new Stack<>();
        s1.push(root);
        s2.push(root.val);
        while (!s1.isEmpty()) {
            int size = s1.size();
            for (int i = 0; i < size; i++) {
                TreeNode node = s1.pop();
                int sum = s2.pop();
                if (node.left == null && node.right == null && sum == targetSum) return true;
                if (node.right != null) {
                    s1.push(node.right);
                    s2.push(sum + node.right.val);
                }
                if (node.left != null) {
                    s1.push(node.left);
                    s2.push(sum + node.left.val);
                }
            }
        }
        return false;
    }
}

class Solution {
    public boolean hasPathSum(TreeNode root, int targetSum) {
        if (root == null) return false;
        Stack<Object> stack = new Stack<>();
        stack.push(root);
        stack.push(root.val);
        while (!stack.isEmpty()) {
            int size = stack.size();
            for (int i = 0; i < size; i += 2) {
                int sum = (Integer) stack.pop();
                TreeNode node = (TreeNode) stack.pop();
                if (node.left == null && node.right == null && sum == targetSum) return true;
                if (node.right != null) {
                    stack.push(node.right);
                    stack.push(sum + node.right.val);
                }
                if (node.left != null) {
                    stack.push(node.left);
                    stack.push(sum + node.left.val);
                }
            }                      
        }
        return false;
    }
}

leetcode 113 (路径总和ii)[https://leetcode.cn/problems/path-sum-ii]

思路

  • 递归法注意回溯减法逼近给定值
  • 迭代法使用栈保存结点和路径

代码

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

    public void traverse(TreeNode node, int targetSum) {
        if (node == null) return;
        path.add(node.val);
        if (node.left == null && node.right == null && node.val == targetSum) {
            res.add(new ArrayList<Integer>(path));
            return;
        }
        if (node.left != null){
            traverse(node.left, targetSum - node.val);
            path.remove(path.size() - 1);
        }
        if (node.right != null) {
            traverse(node.right, targetSum - node.val);
            path.remove(path.size() - 1);
        }
    }
}

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

        Stack<Object> stack = new Stack<>();
        stack.push(root);
        List<Integer> path = new ArrayList<>();
        path.add(root.val);
        stack.push(path);

        while (!stack.isEmpty()) {
            path = (List<Integer>) stack.pop();
            TreeNode node = (TreeNode) stack.pop();

            if (node.left == null && node.right == null && sum(path) == targetSum)
                res.add(new ArrayList<Integer>(path));

            if (node.right != null){
                stack.push(node.right);
                stack.push(concat(path, node.right.val));
            }
            if (node.left != null) {
                stack.push(node.left);
                stack.push(concat(path, node.left.val));
            }
        }
        return res;
    }

    public int sum(List<Integer> list) {
        int sum = 0;
        for (Integer i : list) sum += i;
        return sum;
    }
    public List<Integer> concat(List<Integer> path, int i) {
        List<Integer> res = new ArrayList<>(path);
        res.add(i);
        return res;
    }
}

leetcode 106 (从中序与后序遍历序列构造二叉树)[https://leetcode.cn/problems/construct-binary-tree-from-inorder-and-postorder-traversal]

思路

  • 根据中序遍历和后序遍历特点来递归构造二叉树
  • 中序遍历 左根右, 后序遍历 左右根
  • 从根的位置确定左右子树从而实现递归构造

代码

class Solution {
    public TreeNode buildTree(int[] inorder, int[] postorder) {
        if (inorder.length == 0 || postorder.length == 0) return null;
        TreeNode root = new TreeNode(postorder[postorder.length - 1]);

        for (int i = 0; i < inorder.length; i++) {
            if (postorder[postorder.length - 1] == inorder[i]) {       
                int[] inorderLeft = Arrays.copyOfRange(inorder, 0, i);
                int[] inorderRight = Arrays.copyOfRange(inorder, i + 1, inorder.length);
                int[] postorderLeft = Arrays.copyOfRange(postorder, 0, i);
                int[] postorderRight = Arrays.copyOfRange(postorder, i, postorder.length - 1);

                root.left = buildTree(inorderLeft, postorderLeft);
                root.right = buildTree(inorderRight, postorderRight);
                break;
            }
        }
        return root;
    }
}

leetcode 105 (从前序与中序遍历序列构造二叉树)[]

思路

  • 同理后序 前序为根左右

代码

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

        for (int i = 0; i < preorder.length; i++) {
            if (preorder[0] == inorder[i]) {
                int[] preorderLeft = Arrays.copyOfRange(preorder, 1, i + 1);
                int[] preorderRight = Arrays.copyOfRange(preorder, i + 1, preorder.length);
                int[] inorderLeft = Arrays.copyOfRange(inorder, 0, i);
                int[] inorderRight = Arrays.copyOfRange(inorder, i + 1, inorder.length);

                root.left = buildTree(preorderLeft, inorderLeft);
                root.right = buildTree(preorderRight, inorderRight);
                break;
            }
        }
        return root;
    }
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值