描述
你有一个当前会议列表intervals
,里面表明了每个会议的开始和结束时间,以及一些会议室rooms
。现在有一系列会议ask
需要加入,逐个判断他们能否被安排进当前的会议列表中而不产生冲突。一个会议室在同一时间只能进行一场会议。每个询问都相互独立。
被安排的会议可以拆分。如果需要安排一个[2, 4]
的会议,你可以把它分成[2, 3]
和[3, 4]
两段来进行。
保证输入可以被安排在rooms
个会议室之中
保证任意一个会议的起始时间取值范围是 [1, 50000]
|Intervals| <= 50000
|ask| <= 50000
1 <= rooms <= 20
样例
例 1:
输入:
Intervals:[[1,2],[4,5],[8,10]],rooms = 1,ask: [[2,3],[3,4]]
输出:
[true,true]
解释:
对于[2,3]的询问,我们可以安排一个会议室room0。
以下是room0的会议列表:
[[1,2],[2,3],[4,5],[8,10]]
对于[3,4]的询问,我们可以安排一个会议室room0。
以下是room0的会议列表:
[[1,2],[3,4],[4,5],[8,10]]
例 2:
输入:
[[1,2],[4,5],[8,10]]
1
[[4,5],[5,6]]
输出:
[false,true]
我的第一版 是错的 我把rooms理解成 上面的时间段顺序是固定的 如果 当 后面的时间段的头部比前面的头尾部大的话就是另一个room,但事实上好像是 一个ask可以最多被分成这么多个room的意思
public class Solution {
/**
* @param intervals: the intervals
* @param rooms: the sum of rooms
* @param ask: the ask
* @return: true or false of each meeting
*/
public boolean[] meetingRoomIII(int[][] intervals, int rooms, int[][] ask) {
// Write your code here.
boolean[] MR = new boolean[ask.length];
int MRcount=0;
ArrayList<ArrayList<ArrayList<Integer>>> Sintervals= new ArrayList<ArrayList<ArrayList<Integer>>>(rooms);
for(int i=0; i < rooms; i++) {
Sintervals.add(new ArrayList<ArrayList<Integer>>());
}
int count=0;
int mark=0;
if (rooms==1){
for(int i=0;i<intervals.length;i++){
ArrayList<Integer> c = new ArrayList<Integer>();
c.add(intervals[i][0]);
c.add(intervals[i][1]);
Sintervals.get(0).add(c);
}
}else{
for(int i=1;i<intervals.length;i++){
if(intervals[i][0]<intervals[i-1][1]){
for (int j=mark;j<i;j++){
ArrayList<Integer> c = new ArrayList<Integer>();
c.add(intervals[j][0]);
c.add(intervals[j][1]);
System.out.println(count);
Sintervals.get(count).add(c);
}
count++;
mark=i;
}
}
for (int j=mark;j<intervals.length;j++){
ArrayList<Integer> c = new ArrayList<Integer>();
c.add(intervals[j][0]);
c.add(intervals[j][1]);
Sintervals.get(count).add(c);
}
}
if(Sintervals.get(0).size()>4){
System.out.println(Sintervals.get(3).size());
}
for(int i=0;i<ask.length;i++){
int[][] ask1= new int[ask[i][1]-ask[i][0]][2];
count=0;
for(int p=ask[i][0];p<ask[i][1];p++){
ask1[count][0]=p;
ask1[count][1]=p+1;
count++;
}
boolean[] MRtest= new boolean[ask1.length];
ArrayList<ArrayList<ArrayList<Integer>>> SintervalsTmp= new ArrayList<>(rooms);
for(int p=0;p<rooms;p++)
SintervalsTmp.add(new ArrayList<ArrayList<Integer>>());
for (int p=0;p<Sintervals.size();p++){
for(int k=0;k<Sintervals.get(p).size();k++){
SintervalsTmp.get(p).add(Sintervals.get(p).get(k));
}
}
for(int p=0;p<ask1.length;p++){
for(int k=0;k<rooms;k++){
if(ask1[p][1]<=SintervalsTmp.get(k).get(0).get(0)){
ArrayList<Integer> c = new ArrayList();
c.add(ask1[p][0]);
c.add(ask1[p][1]);
SintervalsTmp.get(k).add(0,c);
MRtest[p]=true;
}
else if(ask1[p][0]>=SintervalsTmp.get(k).get(SintervalsTmp.get(k).size()-1).get(1)){
MRtest[p]=true;
}else{
for(int j=1;j<SintervalsTmp.get(k).size();j++){
if(ask1[p][1]<=SintervalsTmp.get(k).get(j).get(0)&&ask1[p][0]>=SintervalsTmp.get(k).get(j-1).get(1)){
ArrayList<Integer> c = new ArrayList();
c.add(ask1[p][0]);
c.add(ask1[p][1]);
SintervalsTmp.get(k).add(j,c);
MRtest[p]=true;
break;
}
}
}
}
if(MRtest[p]==true){
continue;
}
else{
MRtest[p]=false;
}
}
System.out.println(MRtest.length);
for(int p=0;p<MRtest.length;p++){
System.out.println(MRtest[p]);
if(MRtest[p]==false){
MR[MRcount]=false;
MRcount++;
break;
}
else if(p==MRtest.length-1){
MR[MRcount]=true;
MRcount++;
}
}
}
return MR;
}
}
这是我第二次想出来的:很显然lintcode没有让我过因为代码效率太低 TT
public class Solution {
/**
* @param intervals: the intervals
* @param rooms: the sum of rooms
* @param ask: the ask
* @return: true or false of each meeting
*/
public boolean[] meetingRoomIII(int[][] intervals, int rooms, int[][] ask) {
// Write your code here.
Map<String,Integer> a = new HashMap<String,Integer>();
boolean[] b = new boolean[ask.length];
for (int i=0;i<intervals.length;i++){
for(int j=intervals[i][0];j<intervals[i][1];j++){
String t = Integer.toString(j)+","+Integer.toString(j+1);
if(a.get(t)!=null){
a.put(t,a.get(t)+1);
}
else{
a.put(t,1);
}
}
}
for(int i=0;i<ask.length;i++){
Map<String, Integer> aC= new HashMap(a);
int[][] ask1= new int[ask[i][1]-ask[i][0]][2];
int count=0;
for(int p=ask[i][0];p<ask[i][1];p++){
ask1[count][0]=p;
ask1[count][1]=p+1;
count++;
}
for(int p =0;p<ask1.length;p++){
String t=Integer.toString(ask1[p][0])+","+Integer.toString(ask1[p][1]);
if(aC.get(t)!=null){
if(aC.get(t)+1>rooms){
b[i]=false;
break;
}
else{
aC.put(t,aC.get(t)+1);
}
}
else{
aC.put(t,1);
}
if(p==ask1.length-1)
b[i]=true;
}
}
return b;
}
}
这是第三次:优化不动了
public class Solution {
public boolean[] meetingRoomIII(int[][] intervals, int rooms, int[][] ask) {
// Write your code here.
Map<Integer,Integer> a = new HashMap<Integer,Integer>();
boolean[] b = new boolean[ask.length];
Arrays.fill(b, Boolean.TRUE);
for (int i=0;i<intervals.length;i++){
for(int j=intervals[i][0];j<intervals[i][1];j++){
if(a.get(j)!=null){
a.put(j,a.get(j)+1);
}
else{
a.put(j,1);
}
}
}
for(int i=0;i<ask.length;i++){
if(a.get(ask[i][0])!=null&&ask[i][1]-ask[i][0]==1){
if(a.get(ask[i][0])+1>rooms){
b[i]=false;
}
}else{
for(int p =ask[i][0];p<ask[i][1];p++){
if(a.get(p)!=null){
if(a.get(p)+1>rooms){
b[i]=false;
break;
}
}
}
}
}
return b;
}
}
贴一个可读性强的完美答案供日后研究 :
public class Solution {
/**
* @param intervals: the intervals
* @param rooms: the sum of rooms
* @param ask: the ask
* @return: true or false of each meeting
*/
public boolean[] meetingRoomIII(int[][] intervals, int rooms, int[][] ask) {
// Write your code here.
// 另一种的扫描线Event表示法,只是没有另外写Event class
int[] events = new int[50001]; // events[i]: + 1表示一个会议开始,- 1 表示一个会议结束
int maxEndTime = 0;
for (int[] interval: intervals) {
events[interval[0]]++;
events[interval[1]]--;
maxEndTime = Math.max(maxEndTime, interval[1]);
}
for (int[] query: ask) {
maxEndTime = Math.max(maxEndTime, query[1]);
}
// 前缀和不断维护当前同时存在的会议;起终点只是会议状态发生变化的时候
int numOfMeetings = 0;
int[] sum = new int[50001]; // sum[i] = 0 -> empty; sum[i] = 1 -> not empty
for (int i = 0; i <= maxEndTime; i++) {
numOfMeetings += events[i];
// 这个时间在进行的会议数量到不到rooms个,还有空的会议室
if (numOfMeetings < rooms) {
sum[i] = 0;
} else {
sum[i] = 1;
}
}
// [l,r]要求sum[l...r-1]全为0,sum[l...r-1] = 0
// prefixSum[r - 1 + 1] - prefixSum[l] = 0 <=> prefixSum[r] = prefixSum[l]
int[] prefixSum = new int[sum.length + 1];
prefixSum[0] = 0;
for (int i = 1; i < prefixSum.length; i++) {
prefixSum[i] = prefixSum[i - 1] + sum[i - 1];
}
boolean[] result = new boolean[ask.length];
for (int i = 0; i < ask.length; i++) {
int[] query = ask[i];
int start = query[0];
int end = query[1];
result[i] = prefixSum[end] == prefixSum[start];
}
return result;
}
}