package tree; /** * Created by gouthamvidyapradhan on 08/05/2017. *
* Given a binary tree, find the largest subtree which is a Binary Search Tree (BST), where largest means subtree with largest number of nodes in it. *
* Note: * A subtree must include all of its descendants. * Here's an example: * 10 * / \ * 5 15 * / \ \ * 1 8 7 * The Largest BST Subtree in this case is the highlighted one (5-1-8). * The return value is the subtree's size, which is 3. *
* Follow up: * Can you figure out ways to solve it with O(n) time complexity? *
* Solution: The below solution works with O(n). Validate the BST property from the leaf node and increment the count, as soon as a violation * of BST property is found terminate the count. */ public class LargestBSTSubtree { /** * Range class */ private class Range { int min, max, count; Range(int min, int max, int count) { this.min = min; this.max = max; this.count = count; } } /** * TreeNode */ public static class TreeNode { int val; TreeNode left; TreeNode right; TreeNode(int x) { val = x; } } /** * Count */ private static int count = 0; /** * Main method * * @param args * @throws Exception */ public static void main(String[] args) throws Exception { TreeNode root = new TreeNode(10); root.left = new TreeNode(9); root.left.left = new TreeNode(8); System.out.println(new LargestBSTSubtree().largestBSTSubtree(root)); } /** * Largest subtree count * * @param root root node * @return count */ public int largestBSTSubtree(TreeNode root) { getCount(root); return count; } /** * Get count * * @param node root node * @return Range */ private Range getCount(TreeNode node) { if (node == null) return null; Range left = getCount(node.left); Range right = getCount(node.right); if (left == null && right == null) { count = Math.max(count, 1); return new Range(node.val, node.val, 1); } else if (left == null) { if (node.val < right.min && right.count != -1) //check for -1 ensures that there is no violation of BST property return countMaxAndBuildNewRange(right.count + 1, node.val, right.max); } else if (right == null) { if (node.val > left.max && left.count != -1) return countMaxAndBuildNewRange(left.count + 1, left.min, node.val); } else if (node.val > left.max && node.val < right.min && right.count != -1 && left.count != -1) return countMaxAndBuildNewRange(left.count + right.count + 1, left.min, right.max); return new Range(0, 0, -1); //violation of BST property } /** * Record max and build new range * * @param sum total sum * @param min min * @param max max * @return new Range */ private Range countMaxAndBuildNewRange(int sum, int min, int max) { count = Math.max(count, sum); return new Range(min, max, sum); } }