Logo for ammarahmed.ca
Medium
Oct 05, 2025
#stack

56. Merge Intervals

Problem

Given an array of intervals where intervals[i] = [starti, endi], merge all overlapping intervals, and return an array of the non-overlapping intervals that cover all the intervals in the input.

Example 1:

1Input: intervals = [[1,3],[2,6],[8,10],[15,18]] 2Output: [[1,6],[8,10],[15,18]] 3Explanation: Since intervals [1,3] and [2,6] overlap, merge them into [1,6]. 4

Example 2:

1Input: intervals = [[1,4],[4,5]] 2Output: [[1,5]] 3Explanation: Intervals [1,4] and [4,5] are considered overlapping. 4

Example 3:

1Input: intervals = [[4,7],[1,4]] 2Output: [[1,7]] 3Explanation: Intervals [1,4] and [4,7] are considered overlapping. 4

Constraints:

  • 1 <= intervals.length <= 104
    • intervals[i].length == 2
      • 0 <= starti <= endi <= 104

        Approach

        To solve this problem, we can start by sorting the intervals by the start. After this, we iterate through using a sliding window approach processing each interval with the next one.

        To check if these two intervals will overlap, we check if the end of the first interval is greater than or equal to the start of the next interval. If they are, we merge these by taking the minimum of both starts and the maximum of both ends.

        Practically, to avoid having to delete stuff from an array which will be an O(n) operation everytime we want to delete an interval from the array, we can use top of our resultant list as the the current and the next will be what we are iterating starting from next = 1.

        For example, if we take Example 1, [[1, 3], [2, 6], [8, 10], [15, 18]]

        We'll start by adding the first interval to our result, result = [[1, 3]]

        Then we start iterating with i = 1, with i = 1, our next is next = [2, 6] and our curr is the top of the result, curr = result.top() = [1, 3].

        Since should be merged, we pop the top off of our result and add the merged interval, result = [[1, 6]] and we move on to the next. If there is no merge required, we simply push the next on to the result.

        Complexity

        Time: O(n log n)

        Sorting the array is n log n and then we iterate over the intervals once, O(n)

        Space: O(1)

        Space for the result is not accounted for so we don't create any new space.

        Solution

        1import "sort" 2 3func merge(intervals [][]int) [][]int { 4 if len(intervals) <= 1 { 5 return intervals 6 } 7 8 sort.Slice(intervals, func(i, j int) bool { 9 return intervals[i][0] < intervals[j][0] 10 }) 11 12 result := [][]int{intervals[0]} 13 for i := 1; i < len(intervals); i++ { 14 curr := result[len(result)-1] 15 next := intervals[i] 16 17 if curr[1] >= next[0] { 18 // merge 19 result = result[:len(result)-1] // pop off the top 20 merged := []int{min(curr[0], next[0]), max(curr[1], next[1])} 21 result = append(result, merged) 22 } else { 23 result = append(result, next) 24 } 25 } 26 27 return result 28} 29