Growing with the Web

Check if a binary tree is balanced

Published
Tags:

This article looks at the interview question - Check if a binary tree is balanced.

Analysis

The first thing to do when approaching this problem is to clarify what a balanced tree is as doing this can often help prevent mistakes. A balanced tree is defined as a tree where the depth of all leaf nodes or nodes with single children differ by no more than one.

So the solution should get the node with the minimum depth and the node with the maximum depth and ensure they only differ by 0 or 1.

d_{max} - d_{min} \leq 1

So let’s create separate functions to retrieve the minimum and maximum as it won’t affect the time complexity or the solution since O(cn) = O(n) for some constant c.

Recursive functions to determine the minimum and maximum depth of the tree are fairly trivial to implement. First define the base case; when the node is null return 0. The Recursive case for maxDepth will return the larger of itself called on the left and right children plus 1.

max(maxDepth(left), maxDepth(right)) + 1

For minDepth it will return the smaller of itself called on the left and right children plus 1.

min(minDepth(left), minDepth(right) + 1

Complexity

Both minDepth and maxDepth are called for the tree, each of which traverses each node exactly once. So the time complexity is O(2n) = O(n).

Code

public class Solution {
    /**
     * Determines whether a binary tree is balanced.
     *
     * @param {BinaryTreeNode} root The root of the tree.
     * @returns Whether the tree is balanced.
     */
    public static boolean isBinaryTreeBalanced(BinaryTreeNode root) {
        if (root == null) {
            throw new IllegalArgumentException(
                    "The tree root must be non null");
        }
        return maxDepth(root) - minDepth(root) <= 1;
    }

    /**
     * Determines the minimum depth of a binary tree node.
     *
     * @param node The node to check.
     * @return The minimum depth of a binary tree node.
     */
    private static int minDepth(BinaryTreeNode node) {
        if (node == null) {
            return 0;
        }
        return 1 + Math.min(minDepth(node.left), minDepth(node.right));
    }

    /**
     * Determines the maximum depth of a binary tree node.
     *
     * @param node The node to check.
     * @return The maximum depth of a binary tree node.
     */
    private static int maxDepth(BinaryTreeNode node) {
      if (node == null) {
          return 0;
      }
      return 1 + Math.max(maxDepth(node.left), maxDepth(node.right));
    }
}



public class BinaryTreeNode {
    public Object data;
    public BinaryTreeNode left;
    public BinaryTreeNode right;

    public BinaryTreeNode(Object data, BinaryTreeNode left,
            BinaryTreeNode right) {
        this.data = data;
        this.left = left;
        this.right = right;
    }
}
/**
 * Creates a binary tree node.
 *
 * @constructor
 * @param {Object} data The data associated with this node.
 * @param {BinaryTreeNode} left The left child node.
 * @param {BinaryTreeNode} right The right child node.
 */
function BinaryTreeNode(data, left, right) {
  this.data = data;
  this.left = left;
  this.right = right;
}

/**
 * Determines the minimum depth of a binary tree node.
 *
 * @param {BinaryTreeNode} node The node to check.
 * @return The minimum depth of a binary tree node.
 */
function minDepth(node) {
  if (typeof node === 'undefined') {
    return 0;
  }
  return 1 + Math.min(minDepth(node.left), minDepth(node.right));
}

/**
 * Determines the maximum depth of a binary tree node.
 *
 * @param {BinaryTreeNode} node The node to check.
 * @return The maximum depth of a binary tree node.
 */
function maxDepth(node) {
  if (typeof node === 'undefined') {
    return 0;
  }
  return 1 + Math.max(maxDepth(node.left), maxDepth(node.right));
}

/**
 * Determines whether a binary tree is balanced.
 *
 * @param {BinaryTreeNode} root The root of the tree.
 * @returns Whether the tree is balanced.
 */
function isBinaryTreeBalanced(root) {
  if (typeof root === 'undefined') {
    return undefined;
  }
  return maxDepth(root) - minDepth(root) <= 1;
}

Textbooks

Here are two textbooks that provide many Q&A's like this post that I personally recommend, both were invaluable to me when I was studying for my interviews.

 

Like this article?
Subscribe for more!