[알고리즘 문제해결] leetcode 253 Conference Room II (Greedy + Heap)

leetcode 253 회의실 2호

질문 설명

n개의 회의가 있고 i번째 회의의 시작 시간과 종료 시간은 si s_i 입니다.에스그리고 에이 에이_이이자형. 모든 회의를 주선하는 데 필요한 최소 회의실 수를 찾는 그리디 알고리즘을 설계해 보세요.

회의 시간 일정이 배열되어 있으므로 각 회의 시간에는 시작 시간과 종료 시간 [[s1,e1],[s2,e2],…] (si < ei)이 포함되므로 회의 충돌을 피하기 위해서는 충분한 고려가 필요합니다. 회의실 자원을 사용하여 이러한 회의 준비를 충족하는 데 필요한 최소 회의실 수를 계산하십시오.

입력 : [ [0, 20], [15, 20], [20, 23], [25, 30], [15, 25] ] 출력
: 3

  • 알고리즘 태그
    • 탐욕스러운
    • 더미

잘못된 시도

  • 이 질문 과 비슷한 질문이 있는데, 가장 많은 회의를 갈등 없이 정리하라는 것입니다. 그 질문의 아이디어는 끝나는 시간을 아침부터 밤까지 정렬하는 것입니다. 그러다가 이 질문을 보고 마음을 정했습니다. 클릭했고 곧 제가 틀렸습니다.
  • 반례를 들어보세요
    • 이미지-20230103123339022
    • 이 경우 최소 인원은 2명이며, 1명과 2명이 하나의 회의실을 공유하고, 3명과 4명이 하나의 회의실을 공유합니다.
    • 종료시간이 빠르거나 늦을 경우 처음 4개가 1과 병합을 시도하다가 충돌이 발견되어 4와 2가 병합되고 나머지는 병합되지 않습니다. 총 3개의 방이 있는데, 이는 최적의 솔루션은 아닙니다.

탐욕스러운 솔루션

  • 벡터를 이용하여 기존 회의실의 종료 시간을 기록합니다. end Time List endTimeList시간 목록 _ _ _ _ _ _ _
  • 아침부터 밤까지 모든 회의를 시작 시간별로 정렬합니다.
  • 모든 회의를 순회 ai a_i,현재 회의실에 설정 end Time List endTimeListe n d T im e List i s t 가장 이른 종료 회의 찾기 aearlist a_{earlist}s t 입니다 _ _,判断aearlist a_{earlist}s t 입니다 _ _ai a_i의 종료 시간이 ai a_i 보다 빠른가요?시작 시간e n d T im e List i t 회의실 종료 시간을 업데이트하고 그렇지 않은 경우 end Time List에서 새 회의실을 엽니다 . endTimeListe n d T im e List 에 기록 되어 있습니다 .
  • 시간 복잡도는 O (n 2 ) O(n^2) 입니다.( 2 )
#include <bits/stdc++.h>

//#define debug
#define PII pair<int,int>
#define  x first
#define  y second
using namespace std;

const int N = 100;
PII a[N];
vector<int> end_time_list;//现有会议室的结束时间集合


int main() {
#ifdef debug
    freopen("in.txt", "r", stdin);
#endif
    ios::sync_with_stdio(0);
    int n = 0;
    while (true) {
        int t1, t2;
        cin >> t1 >> t2;
        if (!t1 && !t2)break;
        a[n++] = {t1, t2};
    }
    sort(a, a + n, [&](PII p1, PII p2) { return p1.x < p2.x; });
    for (int i = 0; i < n; ++i) {
        int idx = 0;//最早结束会议室的下标
        for (int j = 0; j < end_time_list.size(); ++j) {
            //找最早结束的会议
            if (end_time_list[j] < end_time_list[idx]) idx = j;
        }
        if (end_time_list.size() && end_time_list[idx] <= a[i].x)//当前会议的开始时间在最早结束的后面,可以复用会议室
            end_time_list[idx] = a[i].y;
        else //不能复用,新增一个会议室
            end_time_list.push_back(a[i].y);
    }
    cout << end_time_list.size() << endl;
    return 0;
}

힙 최적화 솔루션

  • 집합에서 최소값을 찾고 업데이트하는 작업은 O( log ⁡ n ) O(\log n) 의 힙을 사용하여 수행할 수 있습니다.( 로그 _n ) 시간 복잡도
  • C++에서 우선순위 큐를 사용하여 작은 최상위 힙 구현
#include <bits/stdc++.h>

//#define debug
#define PII pair<int,int>
#define  x first
#define  y second
using namespace std;

const int N = 100;
PII a[N];
priority_queue<int, vector<int>, greater<int>> heap;//最早的结束时间


int main() {
#ifdef debug
    freopen("in.txt", "r", stdin);
#endif
    ios::sync_with_stdio(0);
    int n = 0;
    while (true) {
        int t1, t2;
        cin >> t1 >> t2;
        if (!t1 && !t2)break;
        a[n++] = {t1, t2};
    }
    sort(a, a + n, [&](PII p1, PII p2) { return p1.x < p2.x; });
    for (int i = 0; i < n; ++i) {
        if (!heap.empty() && heap.top() <= a[i].x) {
            //复用会议室
            heap.pop();
        }
        heap.push(a[i].y);
    }
    cout << heap.size() << endl;
    return 0;
}

Guess you like

Origin blog.csdn.net/u011459717/article/details/128531372