Line Sweep
)Find the
max
overlap in intervals
= []
open_close for interval in intervals:
0], True)
open_close.append(interval[1], False)
open_close.append(interval[
# note : array.sort() will do `in place` (e.g. return nothing)
= lambda x : (x[1], x[0]) )
open_close.sort( key
open_close
= 0
n = 0
max_num
for i in open_close:
if i[1]:
+= 1
n else:
-= 1
n = max(max_num, n) max_num
# LC 253 Meeting Rooms II
# NOTE : there're also priority queue, sorting approaches
# V0
# IDEA : SCANNING LINE : Sort all time points and label the start and end points. Move a vertical line from left to right.
class Solution:
def minMeetingRooms(self, intervals):
= []
lst """
NOTE THIS !!!
"""
for start, end in intervals:
1))
lst.append((start, -1))
lst.append((end, # all of below sort work
#lst.sort()
= lambda x : [x[0], x[1]])
lst.sort(key = 0, 0
res, curr_rooms for t, n in lst:
+= n
curr_rooms = max(res, curr_rooms)
res return res
# V0''
# IDEA : SCANNING LINE
# Step 1 : split intervals to points, and label start, end point
# Step 2 : reorder the points
# Step 3 : go through every point, if start : result + 1, if end : result -1, and record the maximum result in every iteration
class Solution:
def minMeetingRooms(self, intervals):
if intervals is None or len(intervals) == 0:
return 0
= []
tmp
# set up start and end points
for inter in intervals:
0], True))
tmp.append((inter[1], False))
tmp.append((inter[
# sort
= sorted(tmp, key=lambda v: (v[0], v[1]))
tmp
= 0
n = 0
max_num for arr in tmp:
# start point +1
if arr[1]:
+= 1
n # end point -1
else:
-= 1 # release the meeting room
n = max(n, max_num)
max_num return max_num
# LC 2021. Brightest Position on Street
# V0
# IDEA : Scanning line, LC 253 MEETING ROOM II
class Solution:
def brightestPosition(self, lights: List[List[int]]) -> int:
# light range array
= []
light_r for p,r in lights:
-r,'start'))
light_r.append((p+r+1,'end'))
light_r.append((p= lambda x:x[0])
light_r.sort(key # focus on the boundary of light range
= collections.defaultdict(int)
bright = 0
power for l in light_r:
if 'start' in l:
+= 1
power else:
-= 1
power 0]] = power # NOTE : we update "power" in each iteration
bright[l[
= list(bright.values())
list_bright = list(bright.keys())
list_position
= max(list_bright)
max_bright = list_bright.index(max_bright)
max_bright_index
return list_position[max_bright_index]
# V0'
# IDEA : Scanning line, meeting room
from collections import defaultdict
class Solution(object):
def brightestPosition(self, lights):
# edge case
if not lights:
return
= []
_lights for x in lights:
"""
NOTE this !!!
-> 1) scanning line trick
-> 2) we add 1 to idx for close session (_lights.append([x[0]+x[1]+1, -1]))
"""
0]-x[1], 1])
_lights.append([x[0]+x[1]+1, -1])
_lights.append([x[= lambda x : x)
_lights.sort(key #print ("_lights = " + str(_lights))
= defaultdict(int)
d = 0
up for a, b in _lights:
if b == 1:
+= 1
up else:
-= 1
up = up
d[a] print ("d = " + str(d))
= max(d.values())
_max = [i for i in d if d[i] == _max]
res #print ("res = " + str(res))
return min (res)
# V1
# IDEA : LC 253 MEETING ROOM II
# https://leetcode.com/problems/brightest-position-on-street/discuss/1494005/Python%3A-Basically-meeting-room-II
# IDEA :
# So, the only difference in this problem in comparison to meeting room II is that we have to convert our input into intervals, which is straightforward and basically suggested to use by the first example. So, here is my code and here is meeting rooms II https://leetcode.com/problems/meeting-rooms-ii/
class Solution:
def brightestPosition(self, lights: List[List[int]]) -> int:
= [], [], 0, 0
intervals, heap, res, best for x, y in lights:
-y, x+y])
intervals.append([x
intervals.sort()
for left, right in intervals:
while heap and heap[0] < left:
heappop(heap)
heappush(heap, right)if len(heap) > best:
= len(heap)
best = left
res return res
// java
// LC 731
// V0
// IDEA: SCANNING LINE + CUSTOM SORTING (fixed by gpt)
class MyCalendarTwo {
// Attributes
/**
* NOTE !!!
*
*
* statusList: {time, status, curBooked}
* time: start time or end time
* status: 1 for start, -1 for end
*/
List<Integer[]> statusList;
// Constructor
public MyCalendarTwo() {
this.statusList = new ArrayList<>();
}
public boolean book(int startTime, int endTime) {
// Create intervals
/**
* NOTE !!!
*
* 1) we can init array at once as `new Inteter[] {a,b,c};
* 2) we init curStart, curEnd array at first
*/
Integer[] curStart = new Integer[] { startTime, 1, 0 }; // {time, status, placeholder}
Integer[] curEnd = new Integer[] { endTime, -1, 0 }; // {time, status, placeholder}
// Temporarily add them to the list for simulation
/**
* NOTE !!!
*
* -> we add curStart, curEnd to statusList directly
* -> if new time is `over 2 times overlap`, we can REMOVE them
* from statusList and return `false` in this method,
* and we can keep this method running and validate the
* other input (startTime, endTime)
*/
.add(curStart);
statusList.add(curEnd);
statusList
// Sort by time, then by status (start before end)
/**
* NOTE !!!
*
* custom sorting
*
* -> so, sort time first,
* if time are equal, then sort on `status` (0 or 1),
* `open` goes first, `close` goes next
*/
.sort((x, y) -> {
statusListif (!x[0].equals(y[0])) {
return x[0] - y[0];
}
return x[1] - y[1]; // start (+1) comes before end (-1)
});
// Scanning line to check overlaps
int curBooked = 0;
for (Integer[] interval : statusList) {
+= interval[1];
curBooked if (curBooked >= 3) {
// Remove the temporary intervals
/**
* NOTE !!!
*
* if overlap > 2, we just remove the new added times,
* and return false as method response
*/
.remove(curStart);
statusList.remove(curEnd);
statusListreturn false; // Booking not allowed
}
}
// Booking is valid, keep the intervals
return true;
}
}