Binary Tree Postorder Traverse - How to Succeed in Algorithms Interview
Post Order Traverse
- what we need to return to our caller/parent node
- when handle parent node, children are already handled
- related with divide and conquer, merge sort
- preorder traverse can be faster than post order; as it can exit early
Path may not pass through the root
Binary Tree Reverse Traversal
- LeetCode 971 - Flip Binary Tree To Match Preorder Traversal
public boolean dfs(TreeNode node, int[] v) {
if (node == null) return true;
if (node.val != v[i++]) return false;
if (node.left != null && node.left.val != v[i]) {
res.add(node.val);
return dfs(node.right, v) && dfs(node.left, v);
}
return dfs(node.left, v) && dfs(node.right, v);
}
Simple
public int dfs(TreeNode node) {
if (node == null)
return 0;
int L = dfs(node.left);
int R = dfs(node.right);
ans += Math.abs(L) + Math.abs(R);
return node.val + L + R - 1;
}
public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
if (root == null || root == p || root == q)
return root;
TreeNode leftN = lowestCommonAncestor(root.left, p, q);
TreeNode rightN = lowestCommonAncestor(root.right, p, q);
if (leftN != null && rightN != null)
return root;// case:left is p/q and right is q/p root is LCA
if (leftN == null)
return rightN;// case: p,q both in right subtree, right is LCA
return leftN;// case: both in left, left is LCA
}
TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
if (!root || p == root || q == root) return root;
TreeNode left = lowestCommonAncestor(root->left, p, q);
if (left!=null && left != p && left != q) return left; // optimize
TreeNode right = lowestCommonAncestor(root->right, p , q);
if (left && right) return root;
return left ? left : right;
}
- LeetCode 543 - Diameter of a Binary Tree
int ans;
public int diameterOfBinaryTree(TreeNode root) {
ans = 1;
depth(root);
return ans - 1;
}
public int depth(TreeNode node) {
if (node == null) return 0;
int L = depth(node.left);
int R = depth(node.right);
ans = Math.max(ans, L+R+1);
return Math.max(L, R) + 1;
}
// General tree
public int findDiameter(TreeNode root) {
if (root == null) return 0;
helper(root);
return diameter;
}
int diameter = Integer.MIN_VALUE;
private int helper(TreeNode root) {
int a = Integer.MIN_VALUE;
int b = Integer.MIN_VALUE;
for (TreeNode child : root.children) {
if (child == null) continue;
int tmp = helper(child);
if (tmp > a) { b = a; a = tmp;}
else if (tmp > b) b = tmp;
}
if (b >= 0) diameter = Math.max(diameter, a + b + 2);
if (a >= 0) {
diameter = Math.max(diameter, a + 1);
return a + 1;
}
return 0;
}
- LeetCode 110 - Balanced Binary Tree
- ResultType: {isBalanced, maxDepth}
- not necessary better
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;
}
- LeetCode 124 - Binary Tree Maximum Path Sum
public int maxPathSum(TreeNode root) {
int[] max = new int[1];
max[0] = Integer.MIN_VALUE;
maxPathSum(max, root);
return max[0];
}
private int maxPathSum(int[] max, TreeNode root){
if(root == null)
return 0;
int leftMax = Math.max(0, maxPathSum(max, root.left));
int rightMax = Math.max(0, maxPathSum(max, root.right));
max[0] = Math.max(max[0], root.val+leftMax+rightMax);
return root.val+Math.max(leftMax,rightMax);
}
private class ResultType {
public int sum, size;
public ResultType(int sum, int size) {
this.sum = sum;
this.size = size;
}
}
private TreeNode subtree = null;
private ResultType subtreeResult = null;
public TreeNode findSubtree2(TreeNode root) {
helper(root);
return subtree;
}
private ResultType helper(TreeNode root) {
if (root == null) {
return new ResultType(0, 0);
}
ResultType left = helper(root.left);
ResultType right = helper(root.right);
ResultType result = new ResultType(
left.sum + right.sum + root.val,
left.size + right.size + 1
);
if (subtree == null ||
subtreeResult.sum * result.size < result.sum * subtreeResult.size
) {
subtree = root;
subtreeResult = result;
}
return result;
}