Array
Description
You are given an array of non-overlapping intervals intervals
where intervals[i] = [starti , endi ]
represent the start and the end of the ith
interval and intervals
is sorted in ascending order by starti
. You are also given an interval newInterval = [start, end]
that represents the start and end of another interval.
Insert newInterval
into intervals
such that intervals
is still sorted in ascending order by starti
and intervals
still does not have any overlapping intervals (merge overlapping intervals if necessary).
Return intervals
after the insertion .
Note that you don't need to modify intervals
in-place. You can make a new array and return it.
Example 1:
Input: intervals = [[1,3],[6,9]], newInterval = [2,5]
Output: [[1,5],[6,9]]
Example 2:
Input: intervals = [[1,2],[3,5],[6,7],[8,10],[12,16]], newInterval = [4,8]
Output: [[1,2],[3,10],[12,16]]
Explanation: Because the new interval [4,8] overlaps with [3,5],[6,7],[8,10].
Constraints:
0 <= intervals.length <= 104
intervals[i].length == 2
0 <= starti <= endi <= 105
intervals
is sorted by starti
in ascending order.
newInterval.length == 2
0 <= start <= end <= 105
Solutions
Solution 1: Sorting + Interval Merging
We can first add the new interval newInterval
to the interval list intervals
, and then merge according to the regular method of interval merging.
The time complexity is $O(n \times \log n)$, and the space complexity is $O(n)$. Here, $n$ is the number of intervals.
Python3 Java C++ Go TypeScript Rust C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 class Solution :
def insert (
self , intervals : List [ List [ int ]], newInterval : List [ int ]
) -> List [ List [ int ]]:
def merge ( intervals : List [ List [ int ]]) -> List [ List [ int ]]:
intervals . sort ()
ans = [ intervals [ 0 ]]
for s , e in intervals [ 1 :]:
if ans [ - 1 ][ 1 ] < s :
ans . append ([ s , e ])
else :
ans [ - 1 ][ 1 ] = max ( ans [ - 1 ][ 1 ], e )
return ans
intervals . append ( newInterval )
return merge ( intervals )
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25 class Solution {
public int [][] insert ( int [][] intervals , int [] newInterval ) {
int [][] newIntervals = new int [ intervals . length + 1 ][ 2 ] ;
for ( int i = 0 ; i < intervals . length ; ++ i ) {
newIntervals [ i ] = intervals [ i ] ;
}
newIntervals [ intervals . length ] = newInterval ;
return merge ( newIntervals );
}
private int [][] merge ( int [][] intervals ) {
Arrays . sort ( intervals , ( a , b ) -> a [ 0 ] - b [ 0 ] );
List < int []> ans = new ArrayList <> ();
ans . add ( intervals [ 0 ] );
for ( int i = 1 ; i < intervals . length ; ++ i ) {
int s = intervals [ i ][ 0 ] , e = intervals [ i ][ 1 ] ;
if ( ans . get ( ans . size () - 1 ) [ 1 ] < s ) {
ans . add ( intervals [ i ] );
} else {
ans . get ( ans . size () - 1 ) [ 1 ] = Math . max ( ans . get ( ans . size () - 1 ) [ 1 ] , e );
}
}
return ans . toArray ( new int [ ans . size () ][] );
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 class Solution {
public :
vector < vector < int >> insert ( vector < vector < int >>& intervals , vector < int >& newInterval ) {
intervals . emplace_back ( newInterval );
return merge ( intervals );
}
vector < vector < int >> merge ( vector < vector < int >>& intervals ) {
sort ( intervals . begin (), intervals . end ());
vector < vector < int >> ans ;
ans . emplace_back ( intervals [ 0 ]);
for ( int i = 1 ; i < intervals . size (); ++ i ) {
if ( ans . back ()[ 1 ] < intervals [ i ][ 0 ]) {
ans . emplace_back ( intervals [ i ]);
} else {
ans . back ()[ 1 ] = max ( ans . back ()[ 1 ], intervals [ i ][ 1 ]);
}
}
return ans ;
}
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 func insert ( intervals [][] int , newInterval [] int ) [][] int {
merge := func ( intervals [][] int ) ( ans [][] int ) {
sort . Slice ( intervals , func ( i , j int ) bool { return intervals [ i ][ 0 ] < intervals [ j ][ 0 ] })
ans = append ( ans , intervals [ 0 ])
for _ , e := range intervals [ 1 :] {
if ans [ len ( ans ) - 1 ][ 1 ] < e [ 0 ] {
ans = append ( ans , e )
} else {
ans [ len ( ans ) - 1 ][ 1 ] = max ( ans [ len ( ans ) - 1 ][ 1 ], e [ 1 ])
}
}
return
}
intervals = append ( intervals , newInterval )
return merge ( intervals )
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 function insert ( intervals : number [][], newInterval : number []) : number [][] {
const merge = ( intervals : number [][]) : number [][] => {
intervals . sort (( a , b ) => a [ 0 ] - b [ 0 ]);
const ans : number [][] = [ intervals [ 0 ]];
for ( let i = 1 ; i < intervals . length ; ++ i ) {
if ( ans . at ( - 1 )[ 1 ] < intervals [ i ][ 0 ]) {
ans . push ( intervals [ i ]);
} else {
ans . at ( - 1 )[ 1 ] = Math . max ( ans . at ( - 1 )[ 1 ], intervals [ i ][ 1 ]);
}
}
return ans ;
};
intervals . push ( newInterval );
return merge ( intervals );
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25 impl Solution {
pub fn insert ( intervals : Vec < Vec < i32 >> , new_interval : Vec < i32 > ) -> Vec < Vec < i32 >> {
let mut merged_intervals = intervals . clone ();
merged_intervals . push ( vec! [ new_interval [ 0 ], new_interval [ 1 ]]);
// sort by elem[0]
merged_intervals . sort_by_key ( | elem | elem [ 0 ]);
// merge interval
let mut result = vec! [];
for interval in merged_intervals {
if result . is_empty () {
result . push ( interval );
continue ;
}
let last_elem = result . last_mut (). unwrap ();
if interval [ 0 ] > last_elem [ 1 ] {
result . push ( interval );
} else {
last_elem [ 1 ] = last_elem [ 1 ]. max ( interval [ 1 ]);
}
}
result
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24 public class Solution {
public int [][] Insert ( int [][] intervals , int [] newInterval ) {
int [][] newIntervals = new int [ intervals . Length + 1 ][];
for ( int i = 0 ; i < intervals . Length ; ++ i ) {
newIntervals [ i ] = intervals [ i ];
}
newIntervals [ intervals . Length ] = newInterval ;
return Merge ( newIntervals );
}
public int [][] Merge ( int [][] intervals ) {
intervals = intervals . OrderBy ( a => a [ 0 ]). ToArray ();
var ans = new List < int [] > ();
ans . Add ( intervals [ 0 ]);
for ( int i = 1 ; i < intervals . Length ; ++ i ) {
if ( ans [ ans . Count - 1 ][ 1 ] < intervals [ i ][ 0 ]) {
ans . Add ( intervals [ i ]);
} else {
ans [ ans . Count - 1 ][ 1 ] = Math . Max ( ans [ ans . Count - 1 ][ 1 ], intervals [ i ][ 1 ]);
}
}
return ans . ToArray ();
}
}
Solution 2: One-pass Traversal
We can traverse the interval list intervals
, let the current interval be interval
, and there are three situations for each interval:
The current interval is on the right side of the new interval, that is, $newInterval[1] < interval[0]$. At this time, if the new interval has not been added, then add the new interval to the answer, and then add the current interval to the answer.
The current interval is on the left side of the new interval, that is, $interval[1] < newInterval[0]$. At this time, add the current interval to the answer.
Otherwise, it means that the current interval and the new interval intersect. We take the minimum of the left endpoint of the current interval and the left endpoint of the new interval, and the maximum of the right endpoint of the current interval and the right endpoint of the new interval, as the left and right endpoints of the new interval, and then continue to traverse the interval list.
After the traversal, if the new interval has not been added, then add the new interval to the answer.
The time complexity is $O(n)$, where $n$ is the number of intervals. Ignoring the space consumption of the answer array, the space complexity is $O(1)$.
Python3 Java C++ Go TypeScript Rust C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 class Solution :
def insert (
self , intervals : List [ List [ int ]], newInterval : List [ int ]
) -> List [ List [ int ]]:
st , ed = newInterval
ans = []
insert = False
for s , e in intervals :
if ed < s :
if not insert :
ans . append ([ st , ed ])
insert = True
ans . append ([ s , e ])
elif e < st :
ans . append ([ s , e ])
else :
st = min ( st , s )
ed = max ( ed , e )
if not insert :
ans . append ([ st , ed ])
return ans
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26 class Solution {
public int [][] insert ( int [][] intervals , int [] newInterval ) {
List < int []> ans = new ArrayList <> ();
int st = newInterval [ 0 ] , ed = newInterval [ 1 ] ;
boolean insert = false ;
for ( int [] interval : intervals ) {
int s = interval [ 0 ] , e = interval [ 1 ] ;
if ( ed < s ) {
if ( ! insert ) {
ans . add ( new int [] { st , ed });
insert = true ;
}
ans . add ( interval );
} else if ( e < st ) {
ans . add ( interval );
} else {
st = Math . min ( st , s );
ed = Math . max ( ed , e );
}
}
if ( ! insert ) {
ans . add ( new int [] { st , ed });
}
return ans . toArray ( new int [ ans . size () ][] );
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27 class Solution {
public :
vector < vector < int >> insert ( vector < vector < int >>& intervals , vector < int >& newInterval ) {
vector < vector < int >> ans ;
int st = newInterval [ 0 ], ed = newInterval [ 1 ];
bool insert = false ;
for ( auto & interval : intervals ) {
int s = interval [ 0 ], e = interval [ 1 ];
if ( ed < s ) {
if ( ! insert ) {
ans . push_back ({ st , ed });
insert = true ;
}
ans . push_back ( interval );
} else if ( e < st ) {
ans . push_back ( interval );
} else {
st = min ( st , s );
ed = max ( ed , e );
}
}
if ( ! insert ) {
ans . push_back ({ st , ed });
}
return ans ;
}
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23 func insert ( intervals [][] int , newInterval [] int ) ( ans [][] int ) {
st , ed := newInterval [ 0 ], newInterval [ 1 ]
insert := false
for _ , interval := range intervals {
s , e := interval [ 0 ], interval [ 1 ]
if ed < s {
if ! insert {
ans = append ( ans , [] int { st , ed })
insert = true
}
ans = append ( ans , interval )
} else if e < st {
ans = append ( ans , interval )
} else {
st = min ( st , s )
ed = max ( ed , e )
}
}
if ! insert {
ans = append ( ans , [] int { st , ed })
}
return
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23 function insert ( intervals : number [][], newInterval : number []) : number [][] {
let [ st , ed ] = newInterval ;
const ans : number [][] = [];
let insert = false ;
for ( const [ s , e ] of intervals ) {
if ( ed < s ) {
if ( ! insert ) {
ans . push ([ st , ed ]);
insert = true ;
}
ans . push ([ s , e ]);
} else if ( e < st ) {
ans . push ([ s , e ]);
} else {
st = Math . min ( st , s );
ed = Math . max ( ed , e );
}
}
if ( ! insert ) {
ans . push ([ st , ed ]);
}
return ans ;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28 impl Solution {
pub fn insert ( intervals : Vec < Vec < i32 >> , new_interval : Vec < i32 > ) -> Vec < Vec < i32 >> {
let mut inserted = false ;
let mut result = vec! [];
let ( mut start , mut end ) = ( new_interval [ 0 ], new_interval [ 1 ]);
for iter in intervals . iter () {
let ( cur_st , cur_ed ) = ( iter [ 0 ], iter [ 1 ]);
if cur_ed < start {
result . push ( vec! [ cur_st , cur_ed ]);
} else if cur_st > end {
if ! inserted {
inserted = true ;
result . push ( vec! [ start , end ]);
}
result . push ( vec! [ cur_st , cur_ed ]);
} else {
start = std :: cmp :: min ( start , cur_st );
end = std :: cmp :: max ( end , cur_ed );
}
}
if ! inserted {
result . push ( vec! [ start , end ]);
}
result
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26 public class Solution {
public int [][] Insert ( int [][] intervals , int [] newInterval ) {
var ans = new List < int [] > ();
int st = newInterval [ 0 ], ed = newInterval [ 1 ];
bool insert = false ;
foreach ( var interval in intervals ) {
int s = interval [ 0 ], e = interval [ 1 ];
if ( ed < s ) {
if ( ! insert ) {
ans . Add ( new int []{ st , ed });
insert = true ;
}
ans . Add ( interval );
} else if ( st > e ) {
ans . Add ( interval );
} else {
st = Math . Min ( st , s );
ed = Math . Max ( ed , e );
}
}
if ( ! insert ) {
ans . Add ( new int []{ st , ed });
}
return ans . ToArray ();
}
}
GitHub