Skip to content

Commit e897e81

Browse files
committed
add solution, resources and update readme
1 parent 1216299 commit e897e81

File tree

2 files changed

+135
-1
lines changed

2 files changed

+135
-1
lines changed

README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ As I work through this list I figure I would make a GitHub repo with my solution
3434
### Medium
3535

3636
25. [Maximum Subarray #53](https://github.com/curtisbarnard/leetcode-grind75-javascript/blob/main/medium/maximum-subarray-53.md)
37-
26. Insert Interval #57
37+
26. [Insert Interval #57](https://github.com/curtisbarnard/leetcode-grind75-javascript/blob/main/medium/insert-interval-57.md)
3838
27. 01 Matrix #542
3939
28. [K Closest Points to Origin #973](https://github.com/curtisbarnard/leetcode-grind75-javascript/blob/main/medium/k-closest-origin-973.md)
4040
29. Longest Substring Without Repeating Characters #3
@@ -102,6 +102,7 @@ In order to practice with similar data structures I'll be placing each problem i
102102
- [Majority Element #169](https://github.com/curtisbarnard/leetcode-grind75-javascript/blob/main/easy/majority-element-169.md)
103103
- [Contains Duplicate #217](https://github.com/curtisbarnard/leetcode-grind75-javascript/blob/main/easy/contains-duplicate-217.md)
104104
- [K Closest Points to Origin #973](https://github.com/curtisbarnard/leetcode-grind75-javascript/blob/main/medium/k-closest-origin-973.md)
105+
- [Insert Interval #57](https://github.com/curtisbarnard/leetcode-grind75-javascript/blob/main/medium/insert-interval-57.md)
105106

106107
### Queue
107108

medium/insert-interval-57.md

Lines changed: 133 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,133 @@
1+
# Insert Interval
2+
3+
Page on leetcode: https://leetcode.com/problems/insert-interval/
4+
5+
## Problem Statement
6+
7+
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.
8+
9+
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).
10+
11+
Return intervals after the insertion.
12+
13+
### Constraints
14+
15+
- 0 <= intervals.length <= 104
16+
- intervals[i].length == 2
17+
- 0 <= starti <= endi <= 105
18+
- intervals is sorted by starti in ascending order.
19+
- newInterval.length == 2
20+
- 0 <= start <= end <= 105
21+
22+
### Example
23+
24+
```
25+
Input: intervals = [[1,3],[6,9]], newInterval = [2,5]
26+
Output: [[1,5],[6,9]]
27+
```
28+
29+
```
30+
Input: intervals = [[1,2],[3,5],[6,7],[8,10],[12,16]], newInterval = [4,8]
31+
Output: [[1,2],[3,10],[12,16]]
32+
Explanation: Because the new interval [4,8] overlaps with [3,5],[6,7],[8,10].
33+
```
34+
35+
## Solution
36+
37+
- Need to take care of null case (no intervals provided)
38+
- Need to find either interval before (if no overlap) or interval with overlap of start interval
39+
- Check for overlap of end and subsequent intervals
40+
- Remove intervals that get merged
41+
- If new interval is entirely contained in single existing interval, return original intervals
42+
- Can I use two pointers?
43+
44+
### Pseudocode
45+
46+
1. Create two pointers left, right
47+
2. Iterate thru the array
48+
3. Check if left pointer[1] is greater than start
49+
4. right pointer = left point + 1
50+
5. Check if right pointer[0] is less than end, if not merge with previous
51+
6. Check if right pointer[1] is greater than end, if true merge
52+
53+
### Initial Attempt
54+
55+
```javascript
56+
const insert = function (intervals, newInterval) {
57+
// No existing intervals
58+
if (intervals.length === 0) {
59+
intervals.push(newInterval);
60+
return intervals;
61+
}
62+
63+
let l = 0,
64+
r = 0;
65+
while (r < intervals.length) {
66+
r++;
67+
// New interval completely contained within a single interval
68+
if (intervals[l][0] <= newInterval[0] && intervals[l][1] >= newInterval[1]) {
69+
return intervals;
70+
}
71+
// New interval start overlaps with existing interval
72+
if (intervals[l][1] >= newInterval[0]) {
73+
r--;
74+
while (r < intervals.length) {
75+
r++;
76+
// new interval start overlaps on start, but not end
77+
if (intervals[r] === undefined || intervals[r][0] > newInterval[1]) {
78+
const start = intervals[l][0];
79+
const end = newInterval[1];
80+
intervals.splice(l, r - l, [start, end]);
81+
return intervals;
82+
// new interval spans and overlaps 2+ intervals, including start
83+
} else if (intervals[r][0] <= newInterval[1] && intervals[r][1] > newInterval[1]) {
84+
const start = intervals[l][0];
85+
const end = intervals[r][1];
86+
intervals.splice(l, r - l + 1, [start, end]);
87+
return intervals;
88+
}
89+
r++;
90+
}
91+
// No overlaps
92+
} else if (intervals[l][1] < newInterval[0] && intervals[r][0] > newInterval[1]) {
93+
intervals.splice(l + 1, 0, newInterval);
94+
return intervals;
95+
}
96+
// New interval end overlaps with existing interval
97+
if (intervals[r][0] <= newInterval[1] && intervals[r][1] > newInterval[1]) {
98+
const start = newInterval[0];
99+
const end = intervals[r][1];
100+
intervals.splice(r, 1, [start, end]);
101+
return intervals;
102+
}
103+
l++;
104+
}
105+
};
106+
```
107+
108+
### Optimized Solution
109+
110+
This solution has a time and space complexity of O(n). You can see an explanation of the solution here: https://www.youtube.com/watch?v=A8NUOmlwOlM
111+
112+
```javascript
113+
const insert = function (intervals, newInterval) {
114+
let result = [];
115+
for (let i = 0; i < intervals.length; i++) {
116+
// Check if new interval is before element without overlap
117+
if (intervals[i][0] > newInterval[1]) {
118+
result.push(newInterval);
119+
return result.concat(intervals.slice(i));
120+
// Check if new interval is after element without overlap
121+
} else if (intervals[i][1] < newInterval[0]) {
122+
result.push(intervals[i]);
123+
// Update new interval based on min and max values of overlapping intervals
124+
} else {
125+
newInterval[0] = Math.min(intervals[i][0], newInterval[0]);
126+
newInterval[1] = Math.max(intervals[i][1], newInterval[1]);
127+
}
128+
}
129+
// Need to add new interval to result if the above return never fired. This accounts for cases where new interval is at the end or overlaps with the end element.
130+
result.push(newInterval);
131+
return result;
132+
};
133+
```

0 commit comments

Comments
 (0)