Preorder Traversal:

  • while (!stack.isEmpty || curr != null):表示只要 stack里有数 或者 curr 非空 就有可能有下一个node
  • 当且仅当都为空时 end loop
    // Version 1: stack
    public ArrayList<Integer> preorderTraversal(TreeNode root) {
        // write your code here
        ArrayList<Integer> rst = new ArrayList<>();

        if (root == null) {
            return rst;
        }

        Stack<TreeNode> stack = new Stack<>();
        TreeNode curr = root;

        while (!stack.isEmpty() || curr != null) {

            if (curr != null) {
                rst.add(curr.val);
                stack.push(curr);
                curr = curr.left;
            } else {
                curr = stack.pop();
                curr = curr.right;
            }
        }

        return rst;
    }
//Version 2: Divide & Conquer
public class Solution {
    public ArrayList<Integer> preorderTraversal(TreeNode root) {
        ArrayList<Integer> result = new ArrayList<Integer>();
        // null or leaf
        if (root == null) {
            return result;
        }

        // Divide
        ArrayList<Integer> left = preorderTraversal(root.left);
        ArrayList<Integer> right = preorderTraversal(root.right);

        // Conquer
        result.add(root.val);
        result.addAll(left);
        result.addAll(right);
        return result;
    }
}
//Version 3: Traverse DFS
public class Solution {
    public ArrayList<Integer> preorderTraversal(TreeNode root) {
        ArrayList<Integer> result = new ArrayList<Integer>();
        traverse(root, result);
        return result;
    }
    // 把root为跟的preorder加入result里面
    private void traverse(TreeNode root, ArrayList<Integer> result) {
        if (root == null) {
            return;
        }

        result.add(root.val);
        traverse(root.left, result);
        traverse(root.right, result);
    }
}

Inorder Traversal:

    public ArrayList<Integer> inorderTraversal(TreeNode root) {
        ArrayList<Integer> rst = new ArrayList<>();

        if (root == null) return rst;

        Stack<TreeNode> stack = new Stack<>();
        TreeNode curr = root;

        // 表示只要 stack里有数 或者 curr 非空 就有可能有下一个node
        while (!stack.isEmpty() || curr != null) {
            if (curr != null) {
                stack.push(curr);
                curr = curr.left;
            } else {
                curr = stack.pop();
                rst.add(curr.val);
                curr = curr.right;
            }
        }

        return rst;
    }

Postorder Traversal:

public List<Integer> postorderTraversal(TreeNode root) {
    LinkedList<Integer> rst = new LinkedList<>();
    Deque<TreeNode> stack = new ArrayDeque<>();
    TreeNode curr = root;

    while(!stack.isEmpty() || curr != null) {
        if(curr != null) {
            stack.push(curr);
            result.addFirst(curr.val);  // Reverse the process of preorder
            curr = curr.right;             // Reverse the process of preorder
        } else {
            curr node = stack.pop();
            curr = node.left;           // Reverse the process of preorder
        }
    }
    return result;
}
    public ArrayList<Integer> postorderTraversal(TreeNode root) {
        // write your code here
        ArrayList<Integer> rst = new ArrayList<>();
        if (root == null) return rst;

        Stack<TreeNode> stack1 = new Stack<>();
        Stack<TreeNode> stack2 = new Stack<>();    // also can be linkedlist, use addFirst, then no need to reverse.

        stack1.push(root);

        while (!stack1.isEmpty()) {
            TreeNode curr = stack1.pop();
            TreeNode left = curr.left;
            TreeNode right = curr.right;
            if (left != null) stack1.push(left);
            if (right != null) stack1.push(right);
            stack2.push(curr);
        }

        while (!stack2.isEmpty()) {
            rst.add(stack2.pop().val);
        }

        return rst;
    }

BFS:

    public ArrayList<ArrayList<Integer>> levelOrder(TreeNode root) {
        // write your code here
        ArrayList<ArrayList<Integer>> rst = new ArrayList<>();

        if (root == null) {
            return rst;
        }

        Queue<TreeNode> queue = new LinkedList<>();
        queue.offer(root);

        while (!queue.isEmpty()) {
            int size = queue.size();
            ArrayList<Integer> level = new ArrayList<>();

            for (int i = 0; i < size; i++) {
                TreeNode node = queue.poll();
                level.add(node.val);
                if (node.left != null) {
                    queue.offer(node.left);
                }
                if (node.right != null) {
                    queue.offer(node.right);
                }
            }
            rst.add(level);
        }

        return rst;
    }

Maximum Depth of Binary Tree:

  • divide and conquer
    public int maxDepth(TreeNode root) {
        if (root == null) {
            return 0;
        }

        int left = maxDepth(root.left);
        int right = maxDepth(root.right);

        return Math.max(right, left) + 1;
    }
  • dfs traversal
    int depth;
    public int maxDepth(TreeNode root) {
        depth = 0;
        dfs(root, 1);
        return depth;
    }

    private void dfs(TreeNode root, int currDepth) {
        if (root == null) return;

        depth = Math.max(currDepth, depth);

        dfs(root.left, currDepth + 1);
        dfs(root.right, currDepth + 1);
    }

Balanced Binary Tree:

// Version 1: with ResultType, divide and conquer
class ResultType {
    public boolean isBalanced;
    public int maxDepth;
    public ResultType(boolean isBalanced, int maxDepth) {
        this.isBalanced = isBalanced;
        this.maxDepth = maxDepth;
    }
}

public class Solution {
    public boolean isBalanced(TreeNode root) {
        return helper(root).isBalanced;
    }

    private ResultType helper(TreeNode root) {
        if (root == null) {
            return new ResultType(true, 0);
        }

        ResultType left = helper(root.left);
        ResultType right = helper(root.right);

        // subtree not balance
        if (!left.isBalanced || !right.isBalanced) {
            return new ResultType(false, -1);
        }

        // root not balance
        if (Math.abs(left.maxDepth - right.maxDepth) > 1) {
            return new ResultType(false, -1);
        }

        return new ResultType(true, Math.max(left.maxDepth, right.maxDepth) + 1);
    }
}

// Version 2: without ResultType
public class Solution {
    public boolean isBalanced(TreeNode root) {
        return maxDepth(root) != -1;
    }

    private int maxDepth(TreeNode root) {
        if (root == null) {
            return 0;
        }

        int left = maxDepth(root.left);
        int right = maxDepth(root.right);
        if (left == -1 || right == -1 || Math.abs(left-right) > 1) {
            return -1;
        }
        return Math.max(left, right) + 1;
    }
}

Path Sum ii

  • root -> leaf, not root -> any
public List<List<Integer>> pathSum(TreeNode root, int sum) {

        List<List<Integer>> rst = new ArrayList<>();
        List<Integer> list = new ArrayList<>();

        dc(rst, list, sum, root);        
        return rst;
    }

    private void dc(List<List<Integer>> rst, List<Integer> list, int target, TreeNode node) {

        if (node == null) return;

        list.add(node.val);
        if (node.val == target && node.left == null && node.right == null) {
            rst.add(new ArrayList<>(list));
        }

        dc(rst, list, target - node.val, node.left);
        dc(rst, list, target - node.val, node.right);

        list.remove(list.size() - 1);    
    }

LCA

    public TreeNode lowestCommonAncestor(TreeNode root, TreeNode A, TreeNode B) {
        if (root == null || root.val == A.val || root.val == B.val) {
            return root;
        }

        TreeNode left = lowestCommonAncestor(root.left, A, B);
        TreeNode right = lowestCommonAncestor(root.right, A, B);

        if (left != null && right != null) {
            return root;
        } else if (left != null) {
            return left;
        } else if (right != null) {
            return right;
        } else {
            return null;
        }
    }

LCA in BST

    public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {

        if (root == null) return null;

        if (p.val > root.val && q.val > root.val) return lowestCommonAncestor(root.right, p, q);
        if (p.val < root.val && q.val < root.val) return lowestCommonAncestor(root.left, p, q);

        return root;        
    }

Binary Tree Zigzag Level Order Traversal

  • use two stacks, cf: one queue
  • or same as BFS but Collections.reverse odd level

Binary Tree Level Order Traversal II

  • result put in a stack, then reverse output
  • or use linkedlist, addFirst()

Binary Tree Maximum Path Sum ii:

  • root to any
public int maxPathSum2(TreeNode root) {  
    if (root == null) {  
        return 0;  
    }  
    return root.val + Math.max(0, Math.max(maxPathSum2(root.left), maxPathSum2(root.right)));  
}

Binary Tree Maximum Path Sum

  • any to any
public class Solution {
    /**
     * @param root: The root of binary tree.
     * @return: An integer.
     */
    private class ResultType {
        int singlePath;
        int maxPath;

        ResultType(int singlePath, int maxPath) {
            this.singlePath = singlePath;
            this.maxPath = maxPath;
        }

    } 

    public int maxPathSum(TreeNode root) {
        // write your code here
        ResultType rst = dfs(root);
        return rst.maxPath;
    }

    private ResultType dfs(TreeNode root) {

        if (root == null) {
            return new ResultType(0, Integer.MIN_VALUE);
        }

        ResultType left = dfs(root.left);
        ResultType right = dfs(root.right);

        int singlePath = Math.max(left.singlePath, right.singlePath) + root.val;
        singlePath = Math.max(singlePath, 0);

        // not + root.val b/c plus 的可能为-
        // maxPath 表示有拐的
        int maxPath = Math.max(left.maxPath, right.maxPath);
        maxPath = Math.max(maxPath, left.singlePath + right.singlePath + root.val);

        return new ResultType(singlePath, maxPath);
    } 
}

Binary Tree Path:

  • divide and conquer
    public List<String> binaryTreePaths(TreeNode root) {
        // Write your code here
        List<String> list = new ArrayList<>();
        if (root == null) return list;

        // divide 
        List<String> left = binaryTreePaths(root.left);
        List<String> right = binaryTreePaths(root.right);

        // conquer
        if (left.size() == 0 && right.size() == 0) {
            list.add("" + root.val);
        }

        for (String singlePath : left) {
            list.add(root.val + "->" + singlePath);
        }

        for (String singlePath : right) {
            list.add(root.val + "->" + singlePath);
        }

        return list;
    }
  • backtracking
    public List<String> binaryTreePaths(TreeNode root) {
        // Write your code here
        List<String> rst = new ArrayList<>();
        if (root == null) return rst;

        dfs(root, rst, new StringBuilder());
        return rst;
    }

    private void dfs(TreeNode root, List<String> rst, StringBuilder sb) {
        if (root == null) {
            return;
        }

        int currLength = sb.length();
        sb.append(root.val);

        if (root.left == null && root.right == null) {
            rst.add(new String(sb));
            sb.setLength(currLength);
            return;
        }

        sb.append("->");
        dfs(root.left, rst, sb);
        dfs(root.right, rst, sb);

        sb.setLength(currLength);

        return;
    }

Path Sum - exists:

  • divide and conquer
    public boolean hasPathSum(TreeNode root, int sum) {

        if (root == null) return false;        
        if (sum == root.val && root.left == null && root.right == null) return true;

        boolean left = hasPathSum(root.left, sum - root.val);
        boolean right = hasPathSum(root.right, sum - root.val);

        return left || right;        
    }

Path Sum - all paths:

  • backtracking
public class Solution {
    public List<List<Integer>> pathSum(TreeNode root, int sum) {

        List<List<Integer>> rst = new ArrayList<>();
        List<Integer> list = new ArrayList<>();

        dfs(rst, list, sum, root);        
        return rst;
    }

    private void dfs(List<List<Integer>> rst, List<Integer> list, int target, TreeNode node) {

        if (node == null) return;

        list.add(node.val);
        if (node.val == target && node.left == null && node.right == null) {
            rst.add(new ArrayList<>(list));
        }

        dfs(rst, list, target - node.val, node.left);
        dfs(rst, list, target - node.val, node.right);

        list.remove(list.size() - 1);    
    }
}

LCS:

  • dfs
public class Solution {
    int max = Integer.MIN_VALUE;;
    public int longestConsecutive(TreeNode root) {
        if (root == null) return 0;

        dfs(root, 0, root.val);
        return max;
    }

    private void dfs(TreeNode root, int count, int target) {

        if (root == null) return;
        if (target == root.val) {
            count++;
        } else {
            count = 1;
        }

        max = Math.max(count, max);

        dfs(root.left, count, root.val + 1);
        dfs(root.right, count, root.val + 1);
    }
}
  • divide conquer
  • can not write as:

    • test case: [ 1, 2, 2, 3, [10~100]]
    • if ((root.left != null) && (root.val - root.left.val == -1))

      left = left + 1;  
      

      if ((root.right !=null) && (root.val - root.right.val == -1))

      right = right + 1;
      

      return Math.max(left, right);

public int longestConsecutive(TreeNode root) {
    if(root==null) return 0;
    return Helper(root, 1, root.val);
}

public int Helper(TreeNode root, int count, int val){
    if(root==null) return count;
    count = (root.val - val == 1)?count+1:1;
    int left = Helper(root.left, count, root.val);
    int right = Helper(root.right, count, root.val);
    return Math.max(Math.max(left, right), count);
}

Flatten Binary Tree to LinkedList

// Version 1: Traverse
public class Solution {
    private TreeNode lastNode = null;

    public void flatten(TreeNode root) {
        if (root == null) {
            return;
        }

        if (lastNode != null) {
            lastNode.left = null;
            lastNode.right = root;
        }

        lastNode = root;
        TreeNode right = root.right;
        flatten(root.left); // 因为这一步之后 root.right位置有变 所以需要存盘当前的right
        flatten(right);
    }
}

// version 2: Divide & Conquer
public class Solution {
    /**
     * @param root: a TreeNode, the root of the binary tree
     * @return: nothing
     */
    public void flatten(TreeNode root) {
        helper(root);
    }

    // flatten root and return the last node
    private TreeNode helper(TreeNode root) {
        if (root == null) {
            return null;
        }

        TreeNode leftLast = helper(root.left);
        TreeNode rightLast = helper(root.right);

        // connect leftLast to root.right
        if (leftLast != null) {
            leftLast.right = root.right;
            root.right = root.left;
            root.left = null;
        }

        if (rightLast != null) {
            return rightLast;
        }

        if (leftLast != null) {
            return leftLast;
        }

        return root;
    }
}

// version 3: Non-Recursion
/**
 * Definition of TreeNode:
 * public class TreeNode {
 *     public int val;
 *     public TreeNode left, right;
 *     public TreeNode(int val) {
 *         this.val = val;
 *         this.left = this.right = null;
 *     }
 * }
 */
public class Solution {
    /**
     * @param root: a TreeNode, the root of the binary tree
     * @return: nothing
     */
    public void flatten(TreeNode root) {
        if (root == null) {
            return;
        }

        Stack<TreeNode> stack = new Stack<>();
        stack.push(root);

        while (!stack.empty()) {
            TreeNode node = stack.pop();
            if (node.right != null) {
                stack.push(node.right);
            }
            if (node.left != null) {
                stack.push(node.left);
            }

            // connect 
            node.left = null;
            if (stack.empty()) {
                node.right = null;
            } else {
                node.right = stack.peek();
            }
        }
    }
}

identical binary tree

    public boolean isIdentical(TreeNode node1, TreeNode node2) {
        // Write your code here
        if (node1 == null && node2 == null) {
            return true;
        }

        if (node1 == null || node2 == null) {
            return false;
        }

        if (node1.val != node2.val) {
            return false;
        }

        return isIdentical(node1.left, node2.left) && isIdentical(node2.right, node1.right);
    }

symmetric binary tree

    public boolean isSymmetric(TreeNode root) {
        // Write your code here
        if (root == null) {
            return true;
        }
        return check(root.left, root.right);
    }

    private boolean check(TreeNode root1, TreeNode root2) {
        if (root1 == null && root2 == null) {
            return true;
        }
        if (root1 == null || root2 == null) {
            return false;
        }
        if (root1.val != root2.val) {
            return false;
        }
        return check(root1.left, root2.right) && check(root1.right, root2.left);
    }

results matching ""

    No results matching ""