{"id":3589,"date":"2023-09-11T12:07:02","date_gmt":"2023-09-11T06:37:02","guid":{"rendered":"https:\/\/www.interviewbit.com\/blog\/?p=3589"},"modified":"2023-09-11T12:07:03","modified_gmt":"2023-09-11T06:37:03","slug":"merge-intervals","status":"publish","type":"post","link":"https:\/\/www.interviewbit.com\/blog\/merge-intervals\/","title":{"rendered":"Merge Intervals (With Solution)"},"content":{"rendered":"\n<div class=\"gutentoc tocactive ullist\"><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><li><a href=\"#approach-1-brute-force\">Approach 1: Brute Force<\/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-sorting\">Approach 2: Sorting<\/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-questions\">Practice Questions:<\/a><\/li><li><a href=\"#faq\">FAQ<\/a><\/li><ul class=\"gutentoc-toc__list\"><li><a href=\"#q1-what-is-the-advantage-of-sorting-the-input-array-according-to-start-time\">Q.1: What is the advantage of sorting the input array according to start time?<\/a><\/li><li><a href=\"#q2-how-are-the-intervals-merged\">Q.2: How are the intervals merged?<\/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 <strong>N<\/strong> intervals, where each interval denotes <strong>startTime <\/strong>and <strong>endTime<\/strong>. The task is to merge all overlapping intervals possible and return a list of overlapping intervals in sorted order of their <strong>startTime<\/strong>.<\/p>\n\n\n\n<p><strong>Examples:<\/strong><\/p>\n\n\n\n<p><strong>Input:\u00a0<\/strong><\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img  loading=\"lazy\"  width=\"951\"  height=\"1024\"  src=\"data:image\/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABAQMAAAAl21bKAAAAA1BMVEUAAP+KeNJXAAAAAXRSTlMAQObYZgAAAAlwSFlzAAAOxAAADsQBlSsOGwAAAApJREFUCNdjYAAAAAIAAeIhvDMAAAAASUVORK5CYII=\"  alt=\"merge overlapping intervals\"  class=\"wp-image-3732 pk-lazyload\"  data-pk-sizes=\"auto\"  data-ls-sizes=\"(max-width: 951px) 100vw, 951px\"  data-pk-src=\"https:\/\/www.interviewbit.com\/blog\/wp-content\/uploads\/2021\/11\/merge-overlapping-intervals-951x1024.png\"  data-pk-srcset=\"https:\/\/www.interviewbit.com\/blog\/wp-content\/uploads\/2021\/11\/merge-overlapping-intervals-951x1024.png 951w, https:\/\/www.interviewbit.com\/blog\/wp-content\/uploads\/2021\/11\/merge-overlapping-intervals-279x300.png 279w, https:\/\/www.interviewbit.com\/blog\/wp-content\/uploads\/2021\/11\/merge-overlapping-intervals-768x827.png 768w, https:\/\/www.interviewbit.com\/blog\/wp-content\/uploads\/2021\/11\/merge-overlapping-intervals-380x409.png 380w, https:\/\/www.interviewbit.com\/blog\/wp-content\/uploads\/2021\/11\/merge-overlapping-intervals-550x592.png 550w, https:\/\/www.interviewbit.com\/blog\/wp-content\/uploads\/2021\/11\/merge-overlapping-intervals-800x861.png 800w, https:\/\/www.interviewbit.com\/blog\/wp-content\/uploads\/2021\/11\/merge-overlapping-intervals-1160x1249.png 1160w, https:\/\/www.interviewbit.com\/blog\/wp-content\/uploads\/2021\/11\/merge-overlapping-intervals.png 1354w\" ><\/figure>\n\n\n\n<p><strong>Explanation: <\/strong>Provided in the image<\/p>\n\n\n\n<p><strong>Input: <\/strong>&nbsp;intervals[] = {[1, 3],[2, 6],[8, 10],[15, 18]}<\/p>\n\n\n\n<p><strong>Output:<\/strong> {[1,6],[8,10],[15,18]}<\/p>\n\n\n\n<h2 id=\"approach-1-brute-force\">Approach 1: Brute Force<\/h2>\n\n\n\n<p>First of all, let us try to understand the different types of intervals possible.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img  loading=\"lazy\"  width=\"951\"  height=\"1024\"  src=\"data:image\/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABAQMAAAAl21bKAAAAA1BMVEUAAP+KeNJXAAAAAXRSTlMAQObYZgAAAAlwSFlzAAAOxAAADsQBlSsOGwAAAApJREFUCNdjYAAAAAIAAeIhvDMAAAAASUVORK5CYII=\"  alt=\"different types of intervals\"  class=\"wp-image-3733 pk-lazyload\"  data-pk-sizes=\"auto\"  data-ls-sizes=\"(max-width: 951px) 100vw, 951px\"  data-pk-src=\"https:\/\/www.interviewbit.com\/blog\/wp-content\/uploads\/2021\/11\/different-types-of-intervals-951x1024.png\"  data-pk-srcset=\"https:\/\/www.interviewbit.com\/blog\/wp-content\/uploads\/2021\/11\/different-types-of-intervals-951x1024.png 951w, https:\/\/www.interviewbit.com\/blog\/wp-content\/uploads\/2021\/11\/different-types-of-intervals-279x300.png 279w, https:\/\/www.interviewbit.com\/blog\/wp-content\/uploads\/2021\/11\/different-types-of-intervals-768x827.png 768w, https:\/\/www.interviewbit.com\/blog\/wp-content\/uploads\/2021\/11\/different-types-of-intervals-380x409.png 380w, https:\/\/www.interviewbit.com\/blog\/wp-content\/uploads\/2021\/11\/different-types-of-intervals-550x592.png 550w, https:\/\/www.interviewbit.com\/blog\/wp-content\/uploads\/2021\/11\/different-types-of-intervals-800x861.png 800w, https:\/\/www.interviewbit.com\/blog\/wp-content\/uploads\/2021\/11\/different-types-of-intervals-1160x1249.png 1160w, https:\/\/www.interviewbit.com\/blog\/wp-content\/uploads\/2021\/11\/different-types-of-intervals.png 1354w\" ><\/figure>\n\n\n\n<p>The idea is to try to mark each interval as <strong>non-visited<\/strong> and for each <strong>intervals<\/strong> which is marked as <strong>non-visited<\/strong>, find if another interval exists, which overlaps in any form with the current interval.<\/p>\n\n\n\n<p>If such an interval exists, merge both intervals and mark them <strong>visited<\/strong>.\u00a0<\/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=\"\">bool isOverlap(int minS, int maxE, vector&lt;int> interval)\n{\n    if (minS > interval[1] || maxE &lt; interval[0])\n    {\n        return false;\n    }\n \n    return true;\n}\n \nvector&lt;vector&lt;int>> mergeIntervals(vector&lt;vector&lt;int>> &amp;intervals)\n{\n    int n = intervals.size();\n    vector&lt;vector&lt;int>> res;\n \n    vector&lt;bool> vis(n, false);\n \n    for (int i = 0; i &lt; n; i++)\n    {\n        if (vis[i])\n        {\n            continue;\n        }\n \n        vis[i] = true;\n        int minS = intervals[i][0];\n        int maxE = intervals[i][1];\n \n        while (true)\n        {\n            int cnt = 0;\n \n            for (int j = 0; j &lt; n; j++)\n            {\n                if (!vis[j] &amp;&amp; isOverlap(minS, maxE, intervals[j]))\n                {\n                    vis[j] = true;\n                    minS = min(minS, intervals[j][0]);\n                    maxE = max(maxE, intervals[j][1]);\n                    cnt++;\n                }\n            }\n \n            if (cnt == 0)\n            {\n                break;\n            }\n        }\n \n        vector&lt;int> interval = {minS, maxE};\n        res.push_back(interval);\n    }\n \n    sort(res.begin(), res.end());\n    return res;\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=\"\">public static List &lt; Interval > mergeIntervals(Interval[] intervals) {\n  int n = intervals.length;\n  List &lt; Interval > res = new ArrayList();\n \n  boolean vis[] = new boolean[n];\n \n  for (int i = 0; i &lt; n; i++) {\n    if (vis[i]) {\n      continue;\n    }\n \n    vis[i] = true;\n    int minS = intervals[i].start;\n    int maxE = intervals[i].finish;\n \n    while (true) {\n      int c = 0;\n \n      for (int j = 0; j &lt; n; j++) {\n        if (!vis[j] &amp;&amp; isOverlap(minS, maxE, intervals[j])) {\n          vis[j] = true;\n          minS = Math.min(minS, intervals[j].start);\n          maxE = Math.max(maxE, intervals[j].finish);\n          c++;\n        }\n      }\n \n      if (c == 0) {\n        break;\n      }\n    }\nres.add(new Interval(minS, maxE));\n  }\n \n  Collections.sort(res, new Comparator &lt; Interval > () {\n \n    public int compare(Interval a, Interval b) {\n      if (a.start == b.start) {\n        return a.finish - b.finish;\n      }\n \n      return a.start - b.start;\n    }\n \n  });\n \n  return res;\n}\n \npublic static boolean isOverlap(int minS, int maxE, Interval i) {\n  if (minS > i.finish || maxE &lt; i.start) {\n    return false;\n  }\n \n  return true;\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=\"\">def isOverlap(minS, maxE, i):\n \n    if minS > i.end or maxE &lt; i.start:\n        return False\n \n    return True\n \n \ndef mergeIntervals(intervals):\n    n = len(intervals)\n \n    res = []\n \n    vis = [False for i in range(n)]\n \n    for i in range(n):\n        if vis[i] is True:\n            continue\n \n        vis[i] = True\n        minS = intervals[i].start\n        maxE = intervals[i].end\n \n        while 1:\n            cnt = 0\n \n            for j in range(n):\n \n                if vis[j] is False and isOverlap(minS, maxE, intervals[j]):\n \n                    vis[j] = True\n                    minS = min(minS, intervals[j].start)\n                    maxE = max(maxE, intervals[j].end)\n                    cnt += 1\n            if cnt == 0:\n                break\n \n        a = Solution(minS, maxE)\n        res.append(a)\n \n    return res<\/pre>\n\n\n\n<ul><li><strong>Time Complexity:<\/strong> O(N^2), where N is the total size of the interval array<\/li><li><strong>Space Complexity:<\/strong> O(N), as visiting array is used.<\/li><\/ul>\n\n\n\n<h2 id=\"approach-2-sorting\">Approach 2: Sorting<\/h2>\n\n\n\n<p>Since we need to merge all the possible intervals, instead of finding if an unvisited interval exists that overlaps the current interval, the intervals can be simply sorted according to their starting time.<\/p>\n\n\n\n<p>This ensures that all the intervals are arranged in a contagious fashion.<\/p>\n\n\n\n<p>Let us understand this with an example :<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img  loading=\"lazy\"  width=\"1024\"  height=\"382\"  src=\"data:image\/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABAQMAAAAl21bKAAAAA1BMVEUAAP+KeNJXAAAAAXRSTlMAQObYZgAAAAlwSFlzAAAOxAAADsQBlSsOGwAAAApJREFUCNdjYAAAAAIAAeIhvDMAAAAASUVORK5CYII=\"  alt=\"contagious fashion\"  class=\"wp-image-3734 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\/contagious-fashion-1024x382.png\"  data-pk-srcset=\"https:\/\/www.interviewbit.com\/blog\/wp-content\/uploads\/2021\/11\/contagious-fashion-1024x382.png 1024w, https:\/\/www.interviewbit.com\/blog\/wp-content\/uploads\/2021\/11\/contagious-fashion-300x112.png 300w, https:\/\/www.interviewbit.com\/blog\/wp-content\/uploads\/2021\/11\/contagious-fashion-768x286.png 768w, https:\/\/www.interviewbit.com\/blog\/wp-content\/uploads\/2021\/11\/contagious-fashion-380x142.png 380w, https:\/\/www.interviewbit.com\/blog\/wp-content\/uploads\/2021\/11\/contagious-fashion-550x205.png 550w, https:\/\/www.interviewbit.com\/blog\/wp-content\/uploads\/2021\/11\/contagious-fashion-800x298.png 800w, https:\/\/www.interviewbit.com\/blog\/wp-content\/uploads\/2021\/11\/contagious-fashion-1160x433.png 1160w, https:\/\/www.interviewbit.com\/blog\/wp-content\/uploads\/2021\/11\/contagious-fashion.png 1354w\" ><\/figure>\n\n\n\n<p><strong>Algorithm:<\/strong><\/p>\n\n\n\n<ul><li>Sort the <strong>intervals<\/strong> array according to <strong>startTime<\/strong>.<\/li><li>Create an array to store the <strong>merged <\/strong>intervals.<\/li><li>If the current and previous intervals does not overlap each other, append the current interval to the <strong>merged <\/strong>array.<\/li><li>Else, merge both previous and current intervals and insert it into the <strong>merged <\/strong>array.<\/li><\/ul>\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=\"\">vector &lt; vector &lt; int >> merge(vector &lt; vector &lt; int >> &amp; intervals) {\n  sort(intervals.begin(), intervals.end());\n \n  vector &lt; vector &lt; int >> merged;\n  for (auto interval: intervals) {\n    if (merged.empty() || merged.back()[1] &lt; interval[0]) {\n      merged.push_back(interval);\n    } else {\n      merged.back()[1] = max(merged.back()[1], interval[1]);\n    }\n  }\n  return merged;\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=\"\"> public int[][] merge(int[][] intervals) {\n        Arrays.sort(intervals, (a, b) -> Integer.compare(a[0], b[0]));\n        LinkedList&lt;int[]> merged = new LinkedList&lt;>();\n        for (int[] interval : intervals) {\n            if (merged.isEmpty() || merged.getLast()[1] &lt; interval[0]) {\n                merged.add(interval);\n            }\n            else {\n                merged.getLast()[1] = Math.max(merged.getLast()[1], interval[1]);\n            }\n        }\n        return merged.toArray(new int[merged.size()][]);\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=\"\">def merge(self, intervals: List[List[int]]) -> List[List[int]]:\n \n    intervals.sort(key=lambda x: x[0])\n \n    merged = []\n    for interval in intervals:\n        if not merged or merged[-1][1] &lt; interval[0]:\n            merged.append(interval)\n        else:\n            merged[-1][1] = max(merged[-1][1], interval[1])\n \n    return merged<\/pre>\n\n\n\n<ul><li><strong>Time Complexity:<\/strong> O(NlogN), where N is the total size of the array<\/li><li><strong>Space Complexity:<\/strong> O(N), where N is the total size of the merged array<\/li><\/ul>\n\n\n\n<h2 id=\"practice-questions\">Practice Questions:<\/h2>\n\n\n\n<ul><li><a rel=\"noreferrer noopener\" href=\"https:\/\/www.interviewbit.com\/problems\/merge-overlapping-intervals\/\" target=\"_blank\">Merge Overlapping Intervals<\/a><\/li><\/ul>\n\n\n\n<h2 id=\"faq\">FAQ<\/h2>\n\n\n\n<h3 id=\"q1-what-is-the-advantage-of-sorting-the-input-array-according-to-start-time\"><span id=\"q-1-what-is-the-advantage-of-sorting-the-input-array-according-to-start-time\">Q.1: What is the advantage of sorting the input array according to start time?<\/span><\/h3>\n\n\n\n<p><strong>Ans:<\/strong> Sorting the input array according to start time ensures that all the intervals are in a contagious manner, and helps in merging without having to search for the whole array again.<\/p>\n\n\n\n<h3 id=\"q2-how-are-the-intervals-merged\"><span id=\"q-2-how-are-the-intervals-merged\">Q.2: How are the intervals merged?<\/span><\/h3>\n\n\n\n<p><strong>Ans:<\/strong> The intervals are merged based on their start time and end time.<br>Let us consider two intervals [a, b] and [x, y]<br>Both the intervals overlap, if and only if:\u00a0 b >= x<\/p>\n","protected":false},"excerpt":{"rendered":"Problem Statement Given N intervals, where each interval denotes startTime and endTime. The task is to merge all&hellip;\n","protected":false},"author":5,"featured_media":3731,"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":[555],"amp_enabled":true,"_links":{"self":[{"href":"https:\/\/www.interviewbit.com\/blog\/wp-json\/wp\/v2\/posts\/3589"}],"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=3589"}],"version-history":[{"count":6,"href":"https:\/\/www.interviewbit.com\/blog\/wp-json\/wp\/v2\/posts\/3589\/revisions"}],"predecessor-version":[{"id":23781,"href":"https:\/\/www.interviewbit.com\/blog\/wp-json\/wp\/v2\/posts\/3589\/revisions\/23781"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.interviewbit.com\/blog\/wp-json\/wp\/v2\/media\/3731"}],"wp:attachment":[{"href":"https:\/\/www.interviewbit.com\/blog\/wp-json\/wp\/v2\/media?parent=3589"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.interviewbit.com\/blog\/wp-json\/wp\/v2\/categories?post=3589"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.interviewbit.com\/blog\/wp-json\/wp\/v2\/tags?post=3589"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}