Skip to content

Commit 69cf2c4

Browse files
authored
refactor: js - intervals (neetcode-gh#449)
1 parent 6848691 commit 69cf2c4

File tree

5 files changed

+161
-57
lines changed

5 files changed

+161
-57
lines changed

javascript/252-Meeting-Rooms.js

Lines changed: 25 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,30 @@
11
/**
2-
* @param {number[]} intervals
2+
* https://leetcode.com/problems/meeting-rooms/
3+
* Time O(N * logN) | Space O(1)
4+
* @param {number[][]} intervals
35
* @return {boolean}
46
*/
5-
var canAttendMeetings = function (intervals) {
6-
intervals.sort((a, b) => a[0] - b[0]);
7+
var canAttendMeetings = function(intervals) {
8+
intervals.sort(([ aStart, aEnd ], [ bStart, bEnd ]) => aStart !== bStart
9+
? aStart - bStart
10+
: aEnd - bEnd
11+
);
712

8-
for (let i = 0; i < intervals.length - 1; i++) {
9-
if (intervals[i][1] > intervals[i + 1][0]) {
10-
return false;
11-
}
12-
}
13-
return true;
13+
return canAttend(intervals)
1414
};
15+
16+
const canAttend = (intervals) => {
17+
let prev = intervals.shift();
18+
19+
for (const curr of intervals) {
20+
const [ prevStart, prevEnd ] = prev;
21+
const [ currStart, currEnd ] = curr;
22+
23+
const hasOverlap = currStart < prevEnd;
24+
if (hasOverlap) return false;
25+
26+
prev = curr;
27+
}
28+
29+
return true;
30+
}

javascript/253-Meeting-Rooms-ii.js

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
/**
2+
* https://leetcode.com/problems/meeting-rooms-ii/
3+
* Time O((N * logN) + (M * logM)) | Space O(1)
4+
* @param {number[][]} intervals
5+
* @return {number}
6+
*/
7+
var minMeetingRooms = function(intervals) {
8+
const { start, end } = splitIntervals(intervals);
9+
let [ minRooms, startIndex, endIndex ] = [ 0, 0, 0 ];
10+
11+
while (startIndex < intervals.length) {
12+
const [ currStart, prevEnd ] = [ start[startIndex], end[endIndex] ];
13+
14+
const hasGap = prevEnd <= currStart;
15+
if (hasGap) {
16+
minRooms--;
17+
endIndex++;
18+
}
19+
20+
minRooms++;
21+
startIndex++;
22+
}
23+
24+
return minRooms;
25+
};
26+
27+
const splitIntervals = (intervals, start = [], end = []) => {
28+
for (const [ startTime, endTime ] of intervals) {
29+
start.push(startTime);
30+
end.push(endTime);
31+
}
32+
33+
const comparator = ((a, b) => a - b);
34+
35+
start.sort(comparator);
36+
end.sort(comparator);
37+
38+
return { start, end };
39+
};
Lines changed: 27 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,31 @@
1-
let eraseOverlapIntervals = function (intervals) {
2-
intervals = intervals.sort((a, b) => a[0] - b[1]);
1+
/**
2+
* https://leetcode.com/problems/non-overlapping-intervals/
3+
* Time O(N * logN) | Space O(1)
4+
* @param {number[][]} intervals
5+
* @return {number}
6+
*/
7+
var eraseOverlapIntervals = function(intervals) {
8+
intervals.sort(([ aStart, aEnd ], [ bStart, bEnd ]) => aEnd !== bEnd
9+
? aEnd - bEnd
10+
: aStart - bStart
11+
);
312

4-
let currentEnd = intervals[0][1];
5-
let res = 0;
13+
return getGaps(intervals)
14+
};
15+
16+
const getGaps = (intervals, gaps = 1) => {
17+
const prev = intervals.shift();
18+
19+
for (const curr of intervals) {
20+
const [ prevStart, prevEnd ] = prev;
21+
const [ currStart, currEnd ] = curr;
622

7-
for (let i = 1; i < intervals.length; i++) {
8-
if (currentEnd > intervals[i][0]) {
9-
res += 1;
10-
currentEnd = Math.min(intervals[i][1], currentEnd);
11-
} else {
12-
currentEnd = intervals[i][1];
13-
}
23+
const hasGap = prevEnd <= currStart;
24+
if (!hasGap) continue;
25+
26+
prev[1] = curr[1];
27+
gaps++;
1428
}
1529

16-
return res;
17-
};
30+
return (intervals.length + 1) - gaps;
31+
}

javascript/56-Merge-Intervals.js

Lines changed: 29 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,34 @@
1-
var merge = function (intervals) {
2-
intervals.sort((a, b) => a[0] - b[0]);
1+
/**
2+
* https://leetcode.com/problems/merge-intervals/
3+
* Time O(N * logN) | Space O(N)
4+
* @param {number[][]} intervals
5+
* @return {number[][]}
6+
*/
7+
var merge = function(intervals) {
8+
intervals.sort(([ aStart, aEnd ], [ bStart, bEnd ]) => aStart !== bStart
9+
? aStart - bStart
10+
: aEnd - bEnd
11+
);
312

4-
let res = [intervals[0]];
13+
return mergerInterval(intervals)
14+
};
15+
16+
const mergerInterval = (intervals, merged = []) => {
17+
let prev = intervals.shift();
518

6-
for (let i = 1; i < intervals.length; i++) {
7-
let prev = res[res.length - 1];
19+
for (const curr of intervals) {
20+
const [ prevStart, prevEnd ] = prev;
21+
const [ currStart, currEnd ] = curr;
822

9-
if (prev[1] >= intervals[i][0]) {
10-
prev[1] = Math.max(prev[1], intervals[i][1]);
11-
} else {
12-
res.push(intervals[i]);
23+
const hasOverlap = currStart <= prevEnd;
24+
if (hasOverlap) {
25+
prev[1] = Math.max(prev[1], curr[1]);
26+
continue;
1327
}
28+
29+
merged.push(prev);
30+
prev = curr;
1431
}
15-
return res;
16-
};
32+
33+
return [ ...merged, prev ];
34+
}

javascript/57-Insert-Interval.js

Lines changed: 41 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,43 @@
1-
let insert = function (intervals, newInterval) {
2-
let res = [];
3-
let isAdded = false;
4-
5-
intervals.forEach((int) => {
6-
if (int[0] > newInterval[1]) {
7-
if (!isAdded) {
8-
res.push(newInterval);
9-
isAdded = true;
10-
}
11-
12-
res.push(int);
13-
} else if (int[1] < newInterval[0]) {
14-
res.push(int);
15-
} else {
16-
newInterval[0] = Math.min(newInterval[0], int[0]);
17-
newInterval[1] = Math.max(newInterval[1], int[1]);
18-
}
19-
});
20-
21-
if (!isAdded) {
22-
res.push(newInterval);
23-
}
1+
/**
2+
* https://leetcode.com/problems/insert-interval/
3+
* Time O(N) | Space O(N)
4+
* @param {number[][]} intervals
5+
* @param {number[]} newInterval
6+
* @return {number[][]}
7+
*/
8+
var insert = function(intervals, newInterval) {
9+
const { beforeIndex, before } = getBefore(intervals, newInterval);
10+
const afterIndex = mergeIntervals(intervals, newInterval, beforeIndex);
11+
const after = intervals.slice(afterIndex);
2412

25-
return res;
13+
return [ ...before, newInterval, ...after ];
2614
};
15+
16+
const getBefore = (intervals, newInterval, index = 0, before = []) => {
17+
const hasGap = ([ prevStart, prevEnd ], [ currStart, currEnd ]) =>
18+
prevEnd < currStart;
19+
20+
while (index < intervals.length && hasGap(intervals[index], newInterval)) {
21+
const current = intervals[index];
22+
23+
before.push(current);
24+
index++;
25+
}
26+
27+
return { beforeIndex: index, before };
28+
}
29+
30+
const mergeIntervals = (intervals, newInterval, index) => {
31+
const hasOverlap = ([ prevStart, prevEnd ], [ currStart, currEnd ]) =>
32+
currStart <= prevEnd;
33+
34+
while (index < intervals.length && hasOverlap(newInterval, intervals[index])) {
35+
const current = intervals[index];
36+
37+
newInterval[0] = Math.min(newInterval[0], current[0]);
38+
newInterval[1] = Math.max(newInterval[1], current[1]);
39+
index++;
40+
}
41+
42+
return index;
43+
}

0 commit comments

Comments
 (0)