package com.interview.leetcode.tree; import com.interview.basics.model.tree.BinaryTree; import com.interview.basics.model.tree.BinaryTreeNode; import com.interview.leetcode.utils.TreeNode; import java.util.ArrayList; import java.util.LinkedList; import java.util.List; import java.util.Queue; /** * Created_By: stefanie * Date: 14-11-17 * Time: 下午3:03 */ public class TreeOperations { public static int maxDepth(TreeNode root) { if(root == null) return 0; else return Math.max(maxDepth(root.left), maxDepth(root.right)) + 1; } /** * Given a binary tree, find its minimum depth. */ //Time: O(N), Space: O(1), StackSpace: O(1) public int minDepthDepth(TreeNode root){ if (root == null) return 0; if (root.left == null) return minDepthDepth(root.right) + 1; if (root.right == null) return minDepthDepth(root.left) + 1; return Math.min(minDepthDepth(root.left), minDepthDepth(root.right)) + 1; } //Time: O(N), Space: O(N) public int minDepthLayer(TreeNode root) { if(root == null) return 0; Queue<TreeNode> queue = new LinkedList<>(); int depth = 1; queue.add(root); TreeNode rightMost = root; while(!queue.isEmpty()){ TreeNode node = queue.poll(); if(node.left == null && node.right == null) break; if(node.left != null) queue.add(node.left); if(node.right != null) queue.add(node.right); if(node == rightMost){ rightMost = (node.right != null? node.right : node.left); depth++; } } return depth; } /** * Design an algorithm and write code to find the first common ancestor of two nodes */ //Time: O(N), Space O(1) public TreeNode commonAncestor(TreeNode root, TreeNode n1, TreeNode n2){ if(root == null) return null; if(root == n1 || root == n2) return root; TreeNode left = commonAncestor(root.left, n1, n2); TreeNode right = commonAncestor(root.right, n1, n2); if(left == null) return right; else if(right == null) return left; else return root; } /** * Write code to create a mirroring of a binary tree */ public TreeNode mirrorClone(TreeNode root){ if(root == null) return null; TreeNode clone = new TreeNode(root.val); clone.left = mirrorClone(root.right); clone.right = mirrorClone(root.left); return clone; } /** * Given a binary tree, determine if it is height-balanced. */ //Time: O(N), Space: O(N) public boolean isBalanced(TreeNode root) { return maxDepthIfBalanced(root) != -1; } private int maxDepthIfBalanced(TreeNode root){ if(root == null) return 0; int left = maxDepthIfBalanced(root.left); if(left == -1) return -1; int right = maxDepthIfBalanced(root.right); if(right == -1) return -1; return (Math.abs(left - right) > 1)? -1 : Math.max(left, right) + 1; } /** like reverse linked list, keep cur, parent, left, and do the reverse, be carefully of parent.right. */ //Time: O(N) Space O(1) public TreeNode upsideDownL(TreeNode root) { TreeNode p = root, parent = null, parentRight = null; while (p != null) { TreeNode left = p.left; p.left = parentRight; parentRight = p.right; p.right = parent; parent = p; p = left; } return parent; } //Time: O(N) Space O(N) public static TreeNode upsideDown(TreeNode root) { TreeNode fakeRoot = new TreeNode(0); fakeRoot.left = root; root = upsideDown(root, fakeRoot); root.right = null; root.left = null; return fakeRoot.right; } private static TreeNode upsideDown(TreeNode node, TreeNode prev){ if(node == null) return prev; if(node.left == null){ prev.right = node; return node; } prev = upsideDown(node.left, prev); prev.right = node; prev.left = node.right; return node; } static class NextPopulation{ class TreeLinkNode{ int val; TreeLinkNode left, right, next; } //Time: O(N), Space: O(1) public void connectCompleteTree(TreeLinkNode root) { if(root == null || root.left == null) return; root.left.next = root.right; connectCompleteTree(root.left); connectCompleteTree(root.right); TreeLinkNode right = root.right; while(right != null && root.next != null){ //root.next == null when root is the root node right.next = root.next.left; root = right; right = right.right; } } //Time: O(N), Space: O(N) public void connectNonCompleteTree(TreeLinkNode root) { if(root == null) return; List<TreeLinkNode> current = new ArrayList<>(); current.add(root); while(current.size() > 0){ List<TreeLinkNode> children = new ArrayList<>(); for(TreeLinkNode parent : current){ if(parent.left != null) add(children, parent.left); if(parent.right != null) add(children, parent.right); } current = children; } } private void add(List<TreeLinkNode> list, TreeLinkNode node){ if(list.size() != 0) list.get(list.size() - 1).next = node; list.add(node); } } /** * Given a binary tree which node is a int (positive and negitive), write code to find a sub-tree which node sum is maximal. * based on post-order traverse */ static class MaxSubTree { int max; BinaryTreeNode<Integer> maxNode; public BinaryTreeNode<Integer> find(BinaryTree<Integer> tree) { max = Integer.MIN_VALUE; sum(tree.getRoot()); return maxNode; } public int sum(BinaryTreeNode<Integer> node) { if (node == null) return 0; int count = node.value; count += sum(node.left); count += sum(node.right); if (count > max) { max = count; maxNode = node; } return count; } } /** * Find the max distance of two node in a binary tree. */ static class MaxDistance{ int max; public int maxDistance(TreeNode root){ max = 0; maxHeight(root); return max; } public int maxHeight(TreeNode root){ if(root == null) return 0; int left = maxHeight(root.left); int right = maxHeight(root.right); int cur = left + right + 1; if(cur > max) max = cur; return Math.max(left, right) + 1; } } }