forked from gouthampradhan/leetcode
-
Notifications
You must be signed in to change notification settings - Fork 0
/
LargestBSTSubtree.java
117 lines (108 loc) · 3.2 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
106
107
108
109
110
111
112
113
114
115
116
117
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);
}
}