-
Notifications
You must be signed in to change notification settings - Fork 823
/
Copy pathLargestBSTSubtree.java
105 lines (96 loc) · 2.9 KB
/
LargestBSTSubtree.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
package tree;
/**
* Created by gouthamvidyapradhan on 08/05/2017.
*
* <p>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.
*
* <p>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.
*
* <p>Follow up: Can you figure out ways to solve it with O(n) time complexity?
*
* <p>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);
}
}