package com.interview.leetcode.tree; import com.interview.leetcode.utils.ListNode; import com.interview.leetcode.utils.TreeNode; /** * Created_By: stefanie * Date: 14-11-14 * Time: 上午8:27 */ public class TreeConstruction { /** * given a sorted array, create a balanced BST */ static class SortedArrayBuilder { public TreeNode sortedArrayToBST(int[] num) { return createTree(num, 0, num.length - 1); } public TreeNode createTree(int[] num, int low, int high) { if (low > high) return null; int mid = low + (high - low) / 2; TreeNode node = new TreeNode(num[mid]); node.left = createTree(num, low, mid - 1); node.right = createTree(num, mid + 1, high); return node; } } /** * given a sorted list, create a balanced BST */ static class SortedListBuilder{ ListNode current; public TreeNode sortedListToBST(ListNode head) { if(head == null) return null; current = head; int length = length(head); return buildTree(length); } public int length(ListNode head){ int length = 0; while(head != null){ head = head.next; length++; } return length; } public TreeNode buildTree(int length){ if(length == 0) return null; TreeNode left = buildTree(length / 2); TreeNode node = new TreeNode(current.val); current = current.next; node.left = left; node.right = buildTree(length - 1 - length/2); return node; } } static class PreInOrderBuilder{ int offset = 0; public TreeNode buildTree(int[] preorder, int[] inorder) { offset = 0; return buildTree(preorder, inorder, 0, inorder.length - 1); } public TreeNode buildTree(int[] preorder, int[] inorder, int low, int high){ if(low > high) return null; int cur = preorder[offset++]; int mid = low; while(mid <= high && inorder[mid] != cur) mid++; TreeNode node = new TreeNode(cur); node.left = buildTree(preorder, inorder, low, mid - 1); node.right = buildTree(preorder, inorder, mid + 1, high); return node; } } static class PostInOrderBuilder{ int offset; public TreeNode buildTree(int[] inorder, int[] postorder) { offset = inorder.length - 1; return buildTree(postorder, inorder, 0, inorder.length - 1); } public TreeNode buildTree(int[] postorder, int[] inorder, int low, int high){ if(low > high) return null; int cur = postorder[offset--]; int mid = high; while(mid >= low && inorder[mid] != cur) mid--; TreeNode node = new TreeNode(cur); node.right = buildTree(postorder, inorder, mid + 1, high); node.left = buildTree(postorder, inorder, low, mid - 1); return node; } } /** * Given a binary tree, flatten it to a linked list in-place. * It's a pre-order traverse */ static class TreeFattern{ TreeNode last = null; public void flatten(TreeNode root) { if(root == null) return; TreeNode right = root.right; TreeNode left = root.left; if(last != null){ last.left = null; last.right = root; } last = root; flatten(left); flatten(right); } } /** * Write a method to transfer a BinarySearchTree to a sorted LinkedList without using extra space. * Based on in-order traverse */ static class BSTFattern{ public static TreeNode fattern(TreeNode root){ if(root == null) return null; return fattern(root, null); } private static TreeNode fattern(TreeNode node, TreeNode pre) { if(node.left != null) pre = fattern(node.left, pre); node.left = pre; if(pre != null) pre.right = node; if(node.right != null) return fattern(node.right, node); else return node; } } /** * Write a method to transfer a BinarySearchTree to a sorted LinkedList without using extra space. * Keep tracking the min and max */ static class BSTFatternMinMax{ TreeNode min; TreeNode max; public TreeNode fattern(TreeNode root){ if(root == null) return null; max = null; min = null; fatternNode(root); return min; } public void fatternNode(TreeNode node){ if(node == null) return; fatternNode(node.left); if(min == null) min = node; if(max != null) { max.right = node; node.left = max; } max = node; fatternNode(node.right); } } /** * Two elements of a binary search tree (BST) are swapped by mistake. * Recover the tree without changing its structure. */ //Time: O(N), Space: O(1) static class BSTRecover{ TreeNode first = null; TreeNode second = null; TreeNode last = null; public void recoverTree(TreeNode root) { findBreakPoint(root); int temp = first.val; first.val = second.val; second.val = temp; } public void findBreakPoint(TreeNode node){ if(node == null) return; findBreakPoint(node.left); if(last != null && last.val > node.val){//find a break point; if(first == null) first = last; second = node; } last = node; findBreakPoint(node.right); } } }