56. Merge Intervals

I share my learnings here. Thanks for reading.
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. (link)
Example 1:
Input: intervals = [[1,3],[2,6],[8,10],[15,18]]
Output: [[1,6],[8,10],[15,18]]
Explanation: Since intervals [1,3] and [2,6] overlap, merge them into [1,6].
Example 2:
Input: intervals = [[1,4],[4,5]]
Output: [[1,5]]
Explanation: Intervals [1,4] and [4,5] are considered overlapping.
Constraints:
1 <= intervals.length <= 10<sup>4</sup>intervals[i].length == 20 <= start<sub>i</sub> <= end<sub>i</sub> <= 10<sup>4</sup>
Solution
The main idea is to sort the whole array. This enables pairs, such that overlapping pairs will fall near to the same neighbor. The overlapping condition for any two pairs (a, b) and (c, d) is b <= c.
We combine the intervals by using two variables, start and end. We initially point the start and end to the first interval. We go on expanding the end until we see there is no overlap with the interval. If there is no overlap, then we add the interval (start, end) to the answer and start fresh by pointing (start, end) to the current interval. Finally, we add the interval (start, end) to the answer as it has the last interval range.
Time - O(nlogn)
Space - O(n)
class Solution {
public int[][] merge(int[][] intervals) {
Arrays.sort(intervals, Comparator.comparingInt(interval -> interval[0]));
List<List<Integer>> ans = new ArrayList<>();
int start = intervals[0][0];
int end = intervals[0][1];
for(int[] interval: intervals){
if(end>=interval[0]){
end = Math.max(end, interval[1]);
}
else{
ans.add(Arrays.asList(start,end));
start = interval[0];
end = interval[1];
}
}
ans.add(Arrays.asList(start,end));
int[][] res = ans.stream().map(l->l.stream().mapToInt(Integer::intValue).toArray()).toArray(int[][]::new);
return res;
}
}