{"id":3919,"date":"2023-06-30T18:11:19","date_gmt":"2023-06-30T12:41:19","guid":{"rendered":"https:\/\/www.interviewbit.com\/blog\/?p=3919"},"modified":"2023-06-30T18:11:44","modified_gmt":"2023-06-30T12:41:44","slug":"balanced-binary-tree","status":"publish","type":"post","link":"https:\/\/www.interviewbit.com\/blog\/balanced-binary-tree\/","title":{"rendered":"Balanced Binary Tree"},"content":{"rendered":"\n<p><\/p>\n\n\n\n<div class=\"gutentoc tocactive nostyle\"><div class=\"gutentoc-toc-wrap\"><div class=\"gutentoc-toc-title-wrap\"><div class=\"gutentoc-toc-title\">Table Of Contents<\/div><div id=\"open\" class=\"text_open\">show<\/div><\/div><div id=\"toclist\"><div class=\"gutentoc-toc__list-wrap\"><ul class=\"gutentoc-toc__list\"><li><a href=\"#problem-statement\">Problem Statement<\/a><\/li><ul class=\"gutentoc-toc__list\"><li><a href=\"#-sample-test-cases--\"><strong>Sample Test Cases :<\/strong><\/a><\/li><\/ul><li><a href=\"#approach-1-naive\">Approach 1: Naive<\/a><\/li><ul class=\"gutentoc-toc__list\"><li><a href=\"#c-code\">C++ Code<\/a><\/li><li><a href=\"#java-code\">Java Code<\/a><\/li><li><a href=\"#python-code\">Python Code<\/a><\/li><\/ul><li><a href=\"#approach-2-optimal\">Approach 2: Optimal<\/a><\/li><ul class=\"gutentoc-toc__list\"><li><a href=\"#c-code\">C++ Code<\/a><\/li><li><a href=\"#java-code\">Java Code<\/a><\/li><li><a href=\"#python-code\">Python Code<\/a><\/li><\/ul><li><a href=\"#practice-problem\">Practice Problem:<\/a><\/li><li><a href=\"#faqs\">FAQs<\/a><\/li><ul class=\"gutentoc-toc__list\"><li><a href=\"#q1-in-what-other-types-of-trees-is-the-concept-of-balancing-used\">Q.1: In what other types of trees is the concept of balancing used?<\/a><\/li><li><a href=\"#q2-what-is-the-time-complexity-of-the-depth-function-in-the-naive-approach\">Q.2: What is the time complexity of the depth function in the naive approach?<\/a><\/li><\/ul><\/ul><\/div><\/div><\/div><\/div>\n\n\n\n<h2 id=\"problem-statement\">Problem Statement<\/h2>\n\n\n\n<p>Given a binary tree, determine if is height-balanced.<\/p>\n\n\n\n<p><strong>Height-Balanced: <\/strong>A binary tree is said to be height-balanced if the left and right subtrees of every node differ in height by no more than 1.<\/p>\n\n\n\n<h6 id=\"-sample-test-cases--\"><span id=\"sample-test-cases\"><strong>Sample Test Cases :<\/strong><\/span><\/h6>\n\n\n\n<p><strong>Input 1:<\/strong><\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img  loading=\"lazy\"  width=\"1024\"  height=\"727\"  src=\"data:image\/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABAQMAAAAl21bKAAAAA1BMVEUAAP+KeNJXAAAAAXRSTlMAQObYZgAAAAlwSFlzAAAOxAAADsQBlSsOGwAAAApJREFUCNdjYAAAAAIAAeIhvDMAAAAASUVORK5CYII=\"  alt=\"Input 1\"  class=\"wp-image-3974 pk-lazyload\"  data-pk-sizes=\"auto\"  data-ls-sizes=\"(max-width: 1024px) 100vw, 1024px\"  data-pk-src=\"https:\/\/www.interviewbit.com\/blog\/wp-content\/uploads\/2021\/11\/input-1-1024x727.png\"  data-pk-srcset=\"https:\/\/www.interviewbit.com\/blog\/wp-content\/uploads\/2021\/11\/input-1-1024x727.png 1024w, https:\/\/www.interviewbit.com\/blog\/wp-content\/uploads\/2021\/11\/input-1-300x213.png 300w, https:\/\/www.interviewbit.com\/blog\/wp-content\/uploads\/2021\/11\/input-1-768x545.png 768w, https:\/\/www.interviewbit.com\/blog\/wp-content\/uploads\/2021\/11\/input-1-380x270.png 380w, https:\/\/www.interviewbit.com\/blog\/wp-content\/uploads\/2021\/11\/input-1-550x391.png 550w, https:\/\/www.interviewbit.com\/blog\/wp-content\/uploads\/2021\/11\/input-1-800x568.png 800w, https:\/\/www.interviewbit.com\/blog\/wp-content\/uploads\/2021\/11\/input-1-1160x824.png 1160w, https:\/\/www.interviewbit.com\/blog\/wp-content\/uploads\/2021\/11\/input-1.png 1221w\" ><\/figure>\n\n\n\n<p><strong>Output 1:<\/strong><\/p>\n\n\n\n<p>True<\/p>\n\n\n\n<p><strong><em>Explanation 1:<\/em><\/strong><\/p>\n\n\n\n<p>For every node in the tree, the height of the left and right subtree for that node differs by at most 1.<\/p>\n\n\n\n<p><strong>Input 2:<\/strong><\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img  loading=\"lazy\"  width=\"1024\"  height=\"889\"  src=\"data:image\/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABAQMAAAAl21bKAAAAA1BMVEUAAP+KeNJXAAAAAXRSTlMAQObYZgAAAAlwSFlzAAAOxAAADsQBlSsOGwAAAApJREFUCNdjYAAAAAIAAeIhvDMAAAAASUVORK5CYII=\"  alt=\"input 2\"  class=\"wp-image-3975 pk-lazyload\"  data-pk-sizes=\"auto\"  data-ls-sizes=\"(max-width: 1024px) 100vw, 1024px\"  data-pk-src=\"https:\/\/www.interviewbit.com\/blog\/wp-content\/uploads\/2021\/11\/input-2-1024x889.png\"  data-pk-srcset=\"https:\/\/www.interviewbit.com\/blog\/wp-content\/uploads\/2021\/11\/input-2-1024x889.png 1024w, https:\/\/www.interviewbit.com\/blog\/wp-content\/uploads\/2021\/11\/input-2-300x260.png 300w, https:\/\/www.interviewbit.com\/blog\/wp-content\/uploads\/2021\/11\/input-2-768x666.png 768w, https:\/\/www.interviewbit.com\/blog\/wp-content\/uploads\/2021\/11\/input-2-380x330.png 380w, https:\/\/www.interviewbit.com\/blog\/wp-content\/uploads\/2021\/11\/input-2-550x477.png 550w, https:\/\/www.interviewbit.com\/blog\/wp-content\/uploads\/2021\/11\/input-2-800x694.png 800w, https:\/\/www.interviewbit.com\/blog\/wp-content\/uploads\/2021\/11\/input-2.png 1059w\" ><\/figure>\n\n\n\n<p><strong>Output 2:<\/strong><\/p>\n\n\n\n<p>False<\/p>\n\n\n\n<p><strong>Explanation 2:<\/strong><\/p>\n\n\n\n<p>For node 1, the difference between the heights of the left and right subtree exceeds 1.<\/p>\n\n\n\n<h2 id=\"approach-1-naive\">Approach 1: Naive<\/h2>\n\n\n\n<p>We can solve this problem naively by using a <strong>recursive approach<\/strong>. The approach is as follows:<\/p>\n\n\n\n<ul><li>For each node, calculate the heights of the left and right subtrees of that node.<\/li><li>If the difference between heights is greater than 1, return false.<\/li><li>Else recursively check if the left and right nodes of the original node are also height-balanced.<\/li><\/ul>\n\n\n\n<p id=\"-code--implementation-\"><strong>Code \/ Implementation:<\/strong><\/p>\n\n\n\n<h3 id=\"c-code\"><span id=\"c-code-2\">C++ Code<\/span><\/h3>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"cpp\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">\/**\n * Definition for a binary tree node.\n * struct TreeNode {\n *     int val;\n *     TreeNode *left;\n *     TreeNode *right;\n *     TreeNode() : val(0), left(nullptr), right(nullptr) {}\n *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}\n *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}\n * };\n *\/\nclass Solution {\n  public:\n    int depth(TreeNode * root) {\n      if (root == NULL) {\n        return 0;\n      }\n      return max(depth(root -> left), depth(root -> right)) + 1;\n    }\n  bool isBalanced(TreeNode * root) {\n    if (root == NULL) {\n      return true;\n    }\n    int leftHeight = depth(root -> left);\n    int rightHeight = depth(root -> right);\n    if (abs(leftHeight - rightHeight) &lt;= 1 &amp;&amp; isBalanced(root -> left) &amp;&amp; isBalanced(root -> right)) {\n      return true;\n    } else {\n      return false;\n    }\n  }\n};<\/pre>\n\n\n\n<h3 id=\"java-code\"><span id=\"java-code-2\">Java Code<\/span><\/h3>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">\/**\n * Definition for a binary tree node.\n * public class TreeNode {\n *     int val;\n *     TreeNode left;\n *     TreeNode right;\n *     TreeNode() {}\n *     TreeNode(int val) { this.val = val; }\n *     TreeNode(int val, TreeNode left, TreeNode right) {\n *         this.val = val;\n *         this.left = left;\n *         this.right = right;\n *     }\n * }\n *\/\nclass Solution {\n  public int depth(TreeNode root) {\n    if (root == null) {\n      return 0;\n    }\n    return Math.max(depth(root.left), depth(root.right)) + 1;\n  }\n  public boolean isBalanced(TreeNode root) {\n    if (root == null) {\n      return true;\n    }\n    int leftHeight = depth(root.left);\n    int rightHeight = depth(root.right);\n    if (Math.abs(leftHeight - rightHeight) &lt;= 1 &amp;&amp; isBalanced(root.left) &amp;&amp; isBalanced(root.right)) {\n      return true;\n    } else {\n      return false;\n    }\n  }\n}<\/pre>\n\n\n\n<h3 id=\"python-code\"><span id=\"python-code-2\">Python Code<\/span><\/h3>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"python\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\"># Definition for a binary tree node.\n# class TreeNode(object):\n#     def __init__(self, val=0, left=None, right=None):\n#         self.val = val\n#         self.left = left\n#         self.right = right\nclass Solution(object):\n    def depth(self, root):\n        if root is None:\n            return 0\n        else:\n            return max(self.depth(root.left), self.depth(root.right)) + 1\n\n    def isBalanced(self, root):\n        \"\"\"\n        :type root: TreeNode\n        :rtype: bool\n        \"\"\"\n        if root is None:\n            return True\n        leftHeight = self.depth(root.left)\n        rightHeight = self.depth(root.right)\n        if (\n            abs(leftHeight - rightHeight) &lt;= 1\n            and self.isBalanced(root.left)\n            and self.isBalanced(root.right)\n        ):\n            return True\n        else:\n            return False<\/pre>\n\n\n\n<p><strong>Complexity Analysis:<\/strong><\/p>\n\n\n\n<ul><li>Time Complexity: O(n * n)<\/li><li>Space Complexity: O(1)<\/li><\/ul>\n\n\n\n<h2 id=\"approach-2-optimal\">Approach 2: Optimal<\/h2>\n\n\n\n<p>The optimal approach is the same as the naive approach, but we can optimize the complexity by calculating the height of the subtrees of each node, in the same recursive function call, rather than calling a separate function to calculate the height of subtrees for each node.<\/p>\n\n\n\n<p>Since the recursion progresses in a <strong>bottom-up<\/strong> manner, the heights of the subtree of the children can be used to compute the heights of the subtree of the current node using the relation,<\/p>\n\n\n\n<ul><li>Height of current node = max(height of left subtree, height of right subtree) + 1.<\/li><\/ul>\n\n\n\n<p id=\"-implementation-\"><strong>Code<\/strong> <strong>Implementation:<\/strong><\/p>\n\n\n\n<h3 id=\"c-code\">C++ Code<\/h3>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"cpp\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">\/**\n * Definition for a binary tree node.\n * struct TreeNode {\n *     int val;\n *     TreeNode *left;\n *     TreeNode *right;\n *     TreeNode() : val(0), left(nullptr), right(nullptr) {}\n *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}\n *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}\n * };\n *\/\nclass Solution {\n  public:\n    int check(TreeNode * root, bool &amp; isBalanced) {\n      if (root == NULL) {\n        return 0;\n      }\n      int leftDepth = check(root -> left, isBalanced);\n      int rightDepth = check(root -> right, isBalanced);\n      if (abs(leftDepth - rightDepth) > 1) {\n        isBalanced = false;\n      }\n      return max(leftDepth, rightDepth) + 1;\n    }\n  bool isBalanced(TreeNode * root) {\n    bool bal = true;\n    check(root, bal);\n    return bal;\n  }\n};<\/pre>\n\n\n\n<h3 id=\"java-code\">Java Code<\/h3>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">\/**\n * Definition for a binary tree node.\n * public class TreeNode {\n *     int val;\n *     TreeNode left;\n *     TreeNode right;\n *     TreeNode() {}\n *     TreeNode(int val) { this.val = val; }\n *     TreeNode(int val, TreeNode left, TreeNode right) {\n *         this.val = val;\n *         this.left = left;\n *         this.right = right;\n *     }\n * }\n *\/\nclass Solution {\n  boolean isBalanced = false;\n  public int check(TreeNode root) {\n    if (root == null) {\n      return 0;\n    }\n    int leftDepth = check(root.left);\n    int rightDepth = check(root.right);\n    if (Math.abs(leftDepth - rightDepth) > 1) {\n      isBalanced = false;\n    }\n    return Math.max(leftDepth, rightDepth) + 1;\n  }\n  public boolean isBalanced(TreeNode root) {\n    isBalanced = true;\n    check(root);\n    return isBalanced;\n  }\n}<\/pre>\n\n\n\n<h3 id=\"python-code\">Python Code<\/h3>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"python\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\"># Definition for a binary tree node.\n# class TreeNode(object):\n#     def __init__(self, val=0, left=None, right=None):\n#         self.val = val\n#         self.left = left\n#         self.right = right\nclass Solution(object):\n    def check(self, root, isBalanced):\n        if root is None:\n            return 0\n        leftDepth = self.check(root.left, isBalanced)\n        rightDepth = self.check(root.right, isBalanced)\n        if abs(leftDepth - rightDepth) > 1:\n            self.isBalanced[0] = False\n        return max(leftDepth, rightDepth) + 1\n\n    def isBalanced(self, root):\n        \"\"\"\n        :type root: TreeNode\n        :rtype: bool\n        \"\"\"\n        self.isBalanced = [True]\n        self.check(root, self.isBalanced)\n        return self.isBalanced[0]<\/pre>\n\n\n\n<p><strong>Complexity Analysis:<\/strong><\/p>\n\n\n\n<ul><li>Time Complexity: O(n)<\/li><li>Space Complexity: O(1)<\/li><\/ul>\n\n\n\n<h2 id=\"practice-problem\">Practice Problem:<\/h2>\n\n\n\n<ul><li><a rel=\"noreferrer noopener\" href=\"https:\/\/www.interviewbit.com\/old\/problems\/balanced-binary-tree\/\" target=\"_blank\">Balanced Binary Tree<\/a><\/li><\/ul>\n\n\n\n<h2 id=\"faqs\">FAQs<\/h2>\n\n\n\n<h3 id=\"q1-in-what-other-types-of-trees-is-the-concept-of-balancing-used\"><span id=\"q-1-in-what-other-types-of-trees-is-the-concept-of-balancing-used\">Q.1: In what other types of trees is the concept of balancing used?<\/span><\/h3>\n\n\n\n<p><strong>Ans:<\/strong> <strong>AVL Trees, Red-Black Trees, Splay Trees<\/strong>, etc are a few examples of trees where the concept of self-balancing is used.<\/p>\n\n\n\n<h3 id=\"q2-what-is-the-time-complexity-of-the-depth-function-in-the-naive-approach\"><span id=\"q-2-what-is-the-time-complexity-of-the-depth-function-in-the-naive-approach\">Q.2: What is the time complexity of the depth function in the naive approach?<\/span><\/h3>\n\n\n\n<p><strong>Ans:<\/strong> The depth function in the naive approach works in <strong>O(n)<\/strong>.<\/p>\n","protected":false},"excerpt":{"rendered":"Problem Statement Given a binary tree, determine if is height-balanced. Height-Balanced: A binary tree is said to be&hellip;\n","protected":false},"author":5,"featured_media":3976,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_daextam_enable_autolinks":"1","csco_singular_sidebar":"","csco_page_header_type":"","csco_appearance_grid":"","csco_page_load_nextpost":"","csco_post_video_location":[],"csco_post_video_location_hash":"","csco_post_video_url":"","csco_post_video_bg_start_time":0,"csco_post_video_bg_end_time":0},"categories":[145],"tags":[588],"amp_enabled":true,"_links":{"self":[{"href":"https:\/\/www.interviewbit.com\/blog\/wp-json\/wp\/v2\/posts\/3919"}],"collection":[{"href":"https:\/\/www.interviewbit.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.interviewbit.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.interviewbit.com\/blog\/wp-json\/wp\/v2\/users\/5"}],"replies":[{"embeddable":true,"href":"https:\/\/www.interviewbit.com\/blog\/wp-json\/wp\/v2\/comments?post=3919"}],"version-history":[{"count":4,"href":"https:\/\/www.interviewbit.com\/blog\/wp-json\/wp\/v2\/posts\/3919\/revisions"}],"predecessor-version":[{"id":21012,"href":"https:\/\/www.interviewbit.com\/blog\/wp-json\/wp\/v2\/posts\/3919\/revisions\/21012"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.interviewbit.com\/blog\/wp-json\/wp\/v2\/media\/3976"}],"wp:attachment":[{"href":"https:\/\/www.interviewbit.com\/blog\/wp-json\/wp\/v2\/media?parent=3919"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.interviewbit.com\/blog\/wp-json\/wp\/v2\/categories?post=3919"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.interviewbit.com\/blog\/wp-json\/wp\/v2\/tags?post=3919"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}