1+ package com .ctci .treesandgraphs ;
2+
3+ /**
4+ * Implement a function to check if a binary tree is balanced. For the purposes of this question, a balanced
5+ * tree is defined to be a tree such that the heights of the two subtrees of any node never differ by more than one.
6+ *
7+ * @author rampatra
8+ * @since 2019-02-16
9+ */
10+ public class CheckBalanced {
11+
12+ /**
13+ * Checks whether its left and right child are balanced, if yes then continues down the
14+ * tree or else stops and returns {@code false}. Time complexity: O(n log n) since each
15+ * node is touched once per node above it. Space complexity: O(h) where, h is the height
16+ * of the tree.
17+ *
18+ * @param node reference to the node for which the balanced property needs to be checked
19+ * @return {@code true} if balanced, {@code false} otherwise
20+ */
21+ private static boolean isBalanced (TreeNode node ) {
22+ if (node == null ) return true ;
23+
24+ boolean isBalanced = (height (node .left ) - height (node .right )) <= 1 ;
25+
26+ /* Note: isBalanced is first checked below as there is no point is checking the left and right child
27+ if the current node itself is not balanced. And, as '&&' is a short circuit operator, it won't evaluate
28+ the rest of the conditions if the first condition is false. */
29+ return isBalanced && isBalanced (node .left ) && isBalanced (node .right );
30+ }
31+
32+ private static int height (TreeNode node ) {
33+ if (node == null ) return -1 ;
34+
35+ return Math .max (height (node .left ), height (node .right )) + 1 ;
36+ }
37+
38+ /**
39+ * This approach is a slight modification to the above {@link CheckBalanced#height(TreeNode)} method where
40+ * while calculating the height we also check whether the difference between the left and right child heights
41+ * is more than 1. If yes, we return an error code, which in this case, is {@code Integer.MIN_VALUE}.
42+ * Time complexity: O(n). Space complexity: O(h) where, h is the height of the tree.
43+ *
44+ * @param node reference to the node for which the balanced property needs to be checked
45+ * @return the height of the tree if it's balance, {@code Integer.MIN_VALUE} otherwise
46+ */
47+ private static int checkHeightAndBalance (TreeNode node ) {
48+ if (node == null ) return -1 ;
49+
50+ int leftHeight = checkHeightAndBalance (node .left );
51+ int rightHeight = checkHeightAndBalance (node .right );
52+
53+ if (leftHeight == Integer .MIN_VALUE || rightHeight == Integer .MIN_VALUE || !(leftHeight - rightHeight <= 1 )) {
54+ return Integer .MIN_VALUE ;
55+ }
56+
57+ return Math .max (leftHeight , rightHeight ) + 1 ;
58+ }
59+
60+ private static boolean isBalancedOptimized (TreeNode node ) {
61+ return checkHeightAndBalance (node ) != Integer .MIN_VALUE ;
62+ }
63+
64+ public static void main (String [] args ) {
65+ TreeNode treeRoot = new TreeNode (1 );
66+ treeRoot .left = new TreeNode (2 );
67+ treeRoot .right = new TreeNode (3 );
68+ System .out .println ("Height: " + height (treeRoot ));
69+ System .out .println ("Is Balance: " + isBalanced (treeRoot ));
70+ System .out .println ("Is Balance Optimized: " + isBalancedOptimized (treeRoot ));
71+
72+ treeRoot = new TreeNode (1 );
73+ treeRoot .left = new TreeNode (2 );
74+ treeRoot .right = new TreeNode (3 );
75+ treeRoot .left .left = new TreeNode (4 );
76+ treeRoot .left .left .left = new TreeNode (5 );
77+ System .out .println ("Height: " + height (treeRoot ));
78+ System .out .println ("Is Balance: " + isBalanced (treeRoot ));
79+ System .out .println ("Is Balance Optimized: " + isBalancedOptimized (treeRoot ));
80+ }
81+ }
0 commit comments