題目:1353. 最多可以參加的會議數目
思路:優先隊列實現小頂堆,0(mx*logn)
在第i天,優先選endDay最小的那一個活動進行。那么遍歷每一天,用小頂堆來維護每個活動的最后一天即可,細節看注釋。
C++版本:
class Solution {
public:int maxEvents(vector<vector<int>>& events) {// 找到最后一天int mx=events[0][1];for(auto x:events){mx=max(mx,x[1]);}// 用數組來記錄每一個startDay對應的所有endDay,方便遍歷的時候維護小頂堆vector<vector<int>> v(mx+1);for(auto x:events){v[x[0]].push_back(x[1]);}// 優先隊列實現小頂堆priority_queue<int,vector<int>,greater<>> qu;// 答案int ans=0;// 遍歷每一天for(int i=1;i<=mx;i++){// 先將無法進行的活動都彈出while(!qu.empty()&&qu.top()<i){qu.pop();}// 將所有startDay==i的endDay都加入到小頂堆qufor(auto x:v[i]){qu.push(x);}// 如果隊列不為空,說明當天可選一個活動進行// 這個活動就是最小的endDayif(!qu.empty()){ans++;qu.pop();}}return ans;}
};
JAVA版本:
class Solution {public int maxEvents(int[][] events) {int mx=events[0][1];for(var x:events){mx=Math.max(mx,x[1]);}List<Integer>[] v=new ArrayList[mx+1];Arrays.setAll(v,i-> new ArrayList<>() );for(var x:events){v[x[0]].add(x[1]);}PriorityQueue<Integer> qu =new PriorityQueue<>();int ans=0;for(int i=1;i<=mx;i++){while(!qu.isEmpty()&&qu.peek()<i){qu.poll();}for(var x:v[i]){qu.add(x);}if(!qu.isEmpty()){ans++;qu.poll();}}return ans;}
}