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

513.找树左下角的值

这里是引用

注意:是找最后一层的第一个节点。

最后一层,即求深度最大的叶子节点。

中序后序遍历均可,本题没有处理中间节点,保证优先处理左边节点即可,即左右就行。

class Solution {
    
    int maxDepth = -1;
    int res;
    public int findBottomLeftValue(TreeNode root) {
        // 递归法
        traversal(root, 0);
        return res;
    }

    public void traversal(TreeNode root, int deep) {
        if (root.left == null && root.right == null) {
            if (deep > maxDepth) {
                maxDepth = deep;
                res = root.val;
            }
            return;
        }

        if (root.left != null) traversal(root.left, deep + 1);
        if (root.right != null) traversal(root.right, deep + 1);
        return;
    }
}

112. 路径总和 113.路径总和ii

回溯

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

        List<Integer> path = new ArrayList<>();

        traversal(root, targetSum, res, path);
        return res;
    }

    private void traversal(TreeNode root, int target, List<List<Integer>> res, List<Integer> path) {
        
        // sum += root.val;
        path.add(root.val);
        if (root.left == null && root.right == null) {
            if (target - root.val == 0) {
                res.add(new ArrayList<>(path));
            }
            return;
        }

        if (root.left != null) {
            traversal(root.left, target - root.val, res, path);
            path.remove(path.size() - 1);
        }

        if (root.right != null) {
            traversal(root.right, target - root.val, res, path);
            path.remove(path.size() - 1);
        }
        return;
    }
}

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

记录中序数组的索引
根据前序遍历的第一个值,分割中序数组,中序左数组既为左子树,中序右数组为右子树。
记录中序左子树长度,之后根据中序左子树的长度分割前序数组。

注:不用真的分割数组,记录下标即可。
搞不清下标具体填多少,模拟一下即可。

如此递归,即可。

递归三部曲:

  1. 确定参数:
    traversal(inorder, inStart, inEnd, preorder, preStart, preEnd)
    返回值为TreeNode
    索引下标为左闭右开
  2. 跳出条件:
    if(inStart >= inEnd || preStart >= preEnd) return null
  3. 递归逻辑
rootIndex = map(preorder[preStart]);
root = new TreeNode(inorder[rootIndex]);
lenOfLeft = rootIndex - inStart;

root.left = traversal(inorder, inStart, rootIndex,
					preorder, preStart+1, preStart+1+lenOfLeft);
root.right = traversal(inorder, rootIndex+1, inEnd,
					preorder, preStart+1+lenOfLeft, preEnd);
return root;		

完整代码:

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.put(inorder[i], i);
        }

        return traversal(inorder, 0, inorder.length, preorder, 0, preorder.length);
    }

    public TreeNode traversal(int[] inorder, int inStart, int inEnd, 
                            int[] preorder, int preStart, int preEnd) {

        if (inStart >= inEnd || preStart >= preEnd) {
            return null;
        }

        int rootIndex = map.get(preorder[preStart]);
        TreeNode root = new TreeNode(inorder[rootIndex]);
        
        int lenOfLeft = rootIndex - inStart;
        root.left = traversal(inorder, inStart, rootIndex, 
                            preorder, preStart + 1, preStart + 1 + lenOfLeft);
        root.right = traversal(inorder, rootIndex + 1, inEnd,
                            preorder, preStart + 1 + lenOfLeft, preEnd);

        return root;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值