План курса / Все задачи / Алгоритмы и структуры данных
Число переговорок
средне
# решено
Дан массив отрезков segments, где segments[i] содержит отрезок бронирования комнаты для переговоров: [начало бронирования, конец бронирования]. Сначала комнату освобождают, а потом занимают.
Нужно вернуть минимальное число комнат для переговоров, которое должно быть, чтобы все переговоры могли состояться.
public class Solution
{
public static int CountMeetingRooms(List<List<int>> segments)
{
// Создаем список точек (время, изменение количества комнат)
List<(int time, int change)> points = new List<(int, int)>();
foreach (var segment in segments)
{
// Добавляем точку начала встречи (+1 комната)
points.Add((segment[0], 1));
// Добавляем точку окончания встречи (-1 комната)
points.Add((segment[1], -1));
}
// Сортируем точки по времени
// Если время одинаковое, сначала обрабатываем освобождение комнаты, затем занятие
points.Sort((a, b) =>
{
if (a.time == b.time)
return a.change.CompareTo(b.change); // Сначала -1, потом +1
return a.time.CompareTo(b.time);
});
int maxRoomNumbers = 0;
int currRoomNumbers = 0;
// Для каждого момента времени находим используемое число комнат и выбираем максимальное значение
foreach (var point in points)
{
currRoomNumbers += point.change;
maxRoomNumbers = Math.Max(maxRoomNumbers, currRoomNumbers);
}
return maxRoomNumbers;
}
}
#include <vector>
#include <algorithm>
using namespace std;
int countMeetingRooms(const vector<vector<int>>& segments) {
vector<pair<int, int>> points;
for (const auto& elem : segments) {
points.push_back({elem[0], 1}); // точка, +1 - что нужна еще одна комната
points.push_back({elem[1], -1}); // точка, -1 - что комната освободилась
}
sort(points.begin(), points.end()); // [10, -1] будет перед [10, +1] - сначала освобождают, потом занимают
int maxRoomNumbers = 0;
int currRoomNumbers = 0;
// для каждого момента времени находим используемое число комнат и выбираем максимальное значение
for (const auto& point : points) {
currRoomNumbers += point.second;
maxRoomNumbers = max(maxRoomNumbers, currRoomNumbers);
}
return maxRoomNumbers;
}
package main
import (
"sort"
)
func countMeetingRooms(segments [][]int) int {
points := [][]int{}
for _, elem := range segments {
points = append(points, []int{elem[0], 1}) // точка, +1 - что нужна еще одна комната
points = append(points, []int{elem[1], -1}) // точка, -1 - что комната освободилась
}
sort.Slice(points, func(i, j int) bool {
if points[i][0] == points[j][0] {
return points[i][1] < points[j][1]
}
return points[i][0] < points[j][0]
})
maxRoomNumbers := 0
currRoomNumbers := 0
// для каждого момента времени находим используемое число комнат и выбираем максимальное значение
for _, point := range points {
currRoomNumbers += point[1]
if currRoomNumbers > maxRoomNumbers {
maxRoomNumbers = currRoomNumbers
}
}
return maxRoomNumbers
}
import java.util.*;
public class Solution {
public int countMeetingRooms(List<List<Integer>> segments) {
List<int[]> points = new ArrayList<>();
for (List<Integer> elem : segments) {
points.add(new int[]{elem.get(0), 1}); // точка, +1 - что нужна еще одна комната
points.add(new int[]{elem.get(1), -1}); // точка, -1 - что комната освободилась
}
// сортируем, чтобы освобождение комнаты было перед её занятием
points.sort(Comparator.<int[]>comparingInt(arr -> arr[0]).thenComparingInt(arr -> arr[1]));
int maxRoomNumbers = 0;
int currRoomNumbers = 0;
// для каждого момента времени находим используемое число комнат и выбираем максимальное значение
for (int[] point : points) {
currRoomNumbers += point[1];
maxRoomNumbers = Math.max(maxRoomNumbers, currRoomNumbers);
}
return maxRoomNumbers;
}
}
from typing import *
def count_meeting_rooms(segments: List[List[int]]) -> int:
points = []
for elem in segments:
points.append([elem[0], +1]) # точка, +1 - что нужна еще одна комната
points.append([elem[1], -1]) # точка, -1 - что комната освободилась
points.sort() # [10, -1] будет перед [10, +1] - сначала комнаты освобождают, а потом занимают
max_room_numbers = 0
curr_room_numbers = 0
# для каждого момента времени находим используемое число комнат и выбираем максимальное значение
for point in points:
curr_room_numbers += point[1]
max_room_numbers = max(max_room_numbers, curr_room_numbers)
return max_room_numbers
export function countMeetingRooms(segments) {
let points = [];
for (const elem of segments) {
points.push([elem[0], +1]); // точка, +1 - что нужна еще одна комната
points.push([elem[1], -1]); // точка, -1 - что комната освободилась
}
points.sort((a, b) => {
// Sort by time; if times are the same, prioritize -1 over +1
return a[0] === b[0] ? a[1] - b[1] : a[0] - b[0];
});
let maxRoomNumbers = 0;
let currRoomNumbers = 0;
// для каждого момента времени находим используемое число комнат и выбираем максимальное значение
for (const point of points) {
currRoomNumbers += point[1];
maxRoomNumbers = Math.max(maxRoomNumbers, currRoomNumbers);
}
return maxRoomNumbers;
}
Оценка сложности
Время: O(n*log(n)), где n - длина массива segments