-
Notifications
You must be signed in to change notification settings - Fork 0
Create 253. Meeting Rooms II.md #56
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,110 @@ | ||
| # 253. Meeting Rooms II | ||
| ## STEP1 | ||
| - 何も見ずに解いてみる | ||
| - 252\. Meeting Rooms でみた累積和の考え方を使えば解ける。 | ||
| ```python | ||
| class Solution: | ||
| MAX_TIME = 10 ** 6 | ||
| def minMeetingRooms(self, intervals: List[List[int]]) -> int: | ||
| time_to_num_rooms = [0] * (self.MAX_TIME + 1) | ||
| for start, end in intervals: | ||
| time_to_num_rooms[start] += 1 | ||
| time_to_num_rooms[end] -= 1 | ||
|
|
||
| for i in range(1, len(time_to_num_rooms)): | ||
| time_to_num_rooms[i] += time_to_num_rooms[i - 1] | ||
|
|
||
| return max(time_to_num_rooms) | ||
| ``` | ||
|
|
||
| - MAX_TIME ループするのは非効率なので座標圧縮する。 | ||
| ```python | ||
| def coordinate_compression(coordinate: list[int]) -> dict[int, int]: | ||
| coordinate = sorted(set(coordinate)) | ||
| return {value: i for i, value in enumerate(coordinate)} | ||
|
|
||
|
|
||
| class Solution: | ||
| def minMeetingRooms(self, intervals: List[List[int]]) -> int: | ||
| times = sum(intervals, []) | ||
| time_to_index = coordinate_compression(times) | ||
|
|
||
| index_to_num_rooms = [0] * (len(time_to_index) + 1) | ||
| for start_time, end_time in intervals: | ||
| start_index = time_to_index[start_time] | ||
| end_index = time_to_index[end_time] | ||
| index_to_num_rooms[start_index] += 1 | ||
| index_to_num_rooms[end_index] -= 1 | ||
|
|
||
| for i in range(1, len(index_to_num_rooms)): | ||
| index_to_num_rooms[i] += index_to_num_rooms[i - 1] | ||
| return max(index_to_num_rooms) | ||
| ``` | ||
| ## STEP2 | ||
| ### プルリクやドキュメントを参照 | ||
| - https://github.com/olsen-blue/Arai60/pull/57/files | ||
| > この問題を手で解くとして、解法の取りうる範囲の数字を全部挙げはじめたら結構驚くと思うんですよね。 | ||
|
|
||
| 確かにその通りですね。 | ||
| - https://github.com/olsen-blue/Arai60/pull/57/files#r2030075157 | ||
| > (start, +1), (end, -1) からなる集合を作ってソートする | ||
|
|
||
| なるほど、スマートな方法だと思った。ソートした際に同じ時刻があると −1 のおかげで end が先に来るようになっているのは見落としそう。 | ||
| - https://github.com/Mike0121/LeetCode/pull/28/files#r1633611163 | ||
| 同じ感覚でした。 | ||
|
|
||
| ```python | ||
| class Solution: | ||
| def minMeetingRooms(self, intervals: List[List[int]]) -> int: | ||
| events = [] | ||
| for start, end in intervals: | ||
| events.append((start, 1)) | ||
| events.append((end, -1)) | ||
| events.sort() | ||
|
|
||
| min_rooms = 0 | ||
| num_occupied_rooms = 0 | ||
| for _, delta in events: | ||
| num_occupied_rooms += delta | ||
| min_rooms = max(min_rooms, num_occupied_rooms) | ||
| return min_rooms | ||
| ``` | ||
| - https://github.com/shining-ai/leetcode/blob/main/arai60/54-60_others/56_253_Meeting%20Rooms%20II/level_5.py | ||
| - heap 使うの面白い。開始時刻が早い順に見ていき、heap にためている会議が終了している場合は解放でき新しい終了時刻を追加(部屋の数は増えない)。会議が終わっている部屋がない場合は新しい部屋を追加。room_end_time は短くなることはなく、会議室を使いまわせる場合には増加しないので、len(room_end_time) が必要な会議室の数になる。 | ||
| ```python | ||
| import heapq | ||
|
|
||
|
|
||
| class Solution: | ||
| def minMeetingRooms(self, intervals: List[List[int]]) -> int: | ||
| room_end_time = [] | ||
| for start, end in sorted(intervals): | ||
| if room_end_time and room_end_time[0] <= start: | ||
| heapq.heappop(room_end_time) | ||
| heapq.heappush(room_end_time, end) | ||
| return len(room_end_time) | ||
| ``` | ||
| ## STEP3 | ||
| ### 3回ミスなく書く | ||
| 発生するイベントをソートする方法で書く。 | ||
| ```python | ||
| class Solution: | ||
| def minMeetingRooms(self, intervals: List[List[int]]) -> int: | ||
| events = [] | ||
| for start, end in intervals: | ||
| events.append((start, 1)) # one more room needed | ||
| events.append((end, -1)) # one room freed | ||
|
Comment on lines
+95
to
+96
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Owner
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 個人的には定数にするなら絶対値は同じなので一つかなという気がします。コメントありがとうございます。 NUM_ROOMS_PER_MEETING = 1
events.append((start, +NUM_ROOMS_PER_MEETING)) # secure room(s)
events.append((end, -NUM_ROOMS_PER_MEETING)) # free room(s) |
||
|
|
||
| # if start == end, end (-1) comes before start (+1), | ||
| # so a room is freed before being reused. | ||
| events.sort() | ||
|
|
||
| min_num_rooms = 0 | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. optional: |
||
| num_occupied_rooms = 0 | ||
| for _, delta in events: | ||
| num_occupied_rooms += delta | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 好みだと思いますが、 MEETING_START = 1
MEETING_END = -1
events = []
for start_time, end_time in intervals:
events.append((start_time, MEETING_START))
events.append((end_time, MEETING_END))
num_occupied = 0
num_needed = 0
events.sort()
for event_time, event_type in events:
if event_type == MEETING_END:
num_occupied -= 1
continue
num_occupied += 1
num_needed = max(num_needed, num_occupied)
Owner
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 個人的には違う感覚だなと思いました。 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 回答ありがとうございます。 自分はeventsを(時間, 会議が始まる or 終わる)と捉えていたのですが、tokuhirat さんは初めから(時間, 必要な部屋数が1つ増えるかor1つ減るか)で考えていたということですね。 納得しました。よくよく考えると、tokuhirat さんのやり方の方がシンプルで良いと思いました。ある会議で部屋数を複数個使うみたいな状況にも対応できますし。 |
||
| min_num_rooms = max(min_num_rooms, num_occupied_rooms) | ||
| return min_num_rooms | ||
| ``` | ||
|
|
||
| 4分,3分,3分で3回Accept | ||
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
osモジュールにtimesがあるので別の名前が良いかと思います。
https://docs.python.org/ja/3.13/library/os.html#os.times
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
その観点は見落としていました。ありがとうございます。
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
自分も知りませんでした。ありがとうございます。