We can construct a binary tree with:

But we CANNOT construct a binary tree with postorder and preorder

Untitled

513. Find Bottom Left Tree Value

Recursive, using global variable

class Solution {
    private int maxDepth = -1;
    private int res;

    private void travHelper(TreeNode root, int level) {
        // if null, which should not happen
        if (root == null) return;

        // if leaf
        if (root.left == null && root.right == null) {
            if (level > maxDepth) {
                maxDepth = level;
                res = root.val;
            }
        }

        travHelper(root.left, level + 1);
        travHelper(root.right, level + 1);
    }

    public int findBottomLeftValue(TreeNode root) {
        // root cannot be null

        res = root.val;

        travHelper(root, 1);

        return res;
    }
}

Recursive, not using global variable

// using Pair<Integer, Integer>
class Solution {

    private Pair<Integer, Integer> travHelper(TreeNode root, int level) {
        // if null, which should not happen
        if (root == null) return null;

        // if leaf
        if (root.left == null && root.right == null) {
            return new Pair<>(level, root.val);
        }

        Pair<Integer, Integer> leftRes = (root.left != null) ? travHelper(root.left, level + 1) : null;
        Pair<Integer, Integer> rightRes = (root.right != null) ? travHelper(root.right, level + 1) : null;

        if (root.left == null) {
            return rightRes;
        } else if (root.right == null) {
            return leftRes;
        } else {
            if (leftRes.getKey() >= rightRes.getKey()) return leftRes;
            return rightRes;
        }
    }

    public int findBottomLeftValue(TreeNode root) {
        return travHelper(root, 1).getValue();
    }
}

// using int[]
class Solution {

    private int[] travHelper(TreeNode root, int level) {
        // if null, which should not happen
        if (root == null) return null;

        // if leaf
        if (root.left == null && root.right == null) {
            return new int[] {level, root.val};
        }

        int[] leftRes = (root.left != null) ? travHelper(root.left, level + 1) : null;
        int[] rightRes = (root.right != null) ? travHelper(root.right, level + 1) : null;

        if (root.left == null) {
            return rightRes;
        } else if (root.right == null) {
            return leftRes;
        } else {
            if (leftRes[0] >= rightRes[0]) return leftRes;
            return rightRes;
        }
    }

    public int findBottomLeftValue(TreeNode root) {
        return travHelper(root, 1)[1];
    }
}

Iterative (level order traversal)

class Solution {

    public int findBottomLeftValue(TreeNode root) {
        // root cannot be null

        Deque<TreeNode> nextLevel = new ArrayDeque<>(List.of(root));
        Deque<TreeNode> curLevel;

        do {
            curLevel = nextLevel;
            nextLevel = new ArrayDeque<>();
            for (TreeNode node : curLevel) {
                if (node.left != null) nextLevel.add(node.left);
                if (node.right != null) nextLevel.add(node.right);
            }
        } while (!nextLevel.isEmpty());

        return curLevel.peek().val;
    }
}

112. Path Sum

Recursive

class Solution {
    public boolean sumHelper(TreeNode root, int targetSum, int curSum) {
        if (root == null) return false;

        if (root.left == null && root.right == null) return (targetSum == curSum + root.val);

        return sumHelper(root.left, targetSum, curSum + root.val) || sumHelper(root.right, targetSum, curSum + root.val);
    }

    public boolean hasPathSum(TreeNode root, int targetSum) {
        return sumHelper(root, targetSum, 0);
    }
}

Can do better if we use parameter to record “left over” value - don’t even need a helper function

class Solution {

    public boolean hasPathSum(TreeNode root, int targetSum) {
        if (root == null) 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);
    }
}

Iterative

class Solution {

    public boolean hasPathSum(TreeNode root, int targetSum) {
        if (root == null) return false;
        
        // the integer will store the sum up to (including) the current node
        Deque<Pair<TreeNode, Integer>> st = new ArrayDeque<>();
        st.push(new Pair<>(root, root.val));

        while (!st.isEmpty()) {
            Pair<TreeNode, Integer> curPair = st.pop();
            TreeNode curNode = curPair.getKey();
            
            // if the curNode is leaf, check for sum equality
            if (curNode.left == null && curNode.right == null && curPair.getValue() == targetSum) return true;

            if (curNode.right != null) st.push(new Pair<>(curNode.right, curPair.getValue() + curNode.right.val));
            if (curNode.left != null) st.push(new Pair<>(curNode.left, curPair.getValue() + curNode.left.val));
        }

        return false;
    }
}