給你一個整數?eventTime
?表示一個活動的總時長,這個活動開始于?t = 0
?,結束于?t = eventTime
?。
同時給你兩個長度為?n
?的整數數組?startTime
?和?endTime
?。它們表示這次活動中?n
?個時間?沒有重疊?的會議,其中第?i
?個會議的時間為?[startTime[i], endTime[i]]
?。
你可以重新安排?至多?一個會議,安排的規則是將會議時間平移,且保持原來的?會議時長?,你的目的是移動會議后?最大化?相鄰兩個會議之間的?最長?連續空余時間。
請你返回重新安排會議以后,可以得到的?最大?空余時間。
注意,會議?不能?安排到整個活動的時間以外,且會議之間需要保持互不重疊。
注意:重新安排會議以后,會議之間的順序可以發生改變。
示例 1:
輸入:eventTime = 5, startTime = [1,3], endTime = [2,5]
輸出:2
解釋:
將?[1, 2]
?的會議安排到?[2, 3]
?,得到空余時間?[0, 2]
?。
示例 2:
輸入:eventTime = 10, startTime = [0,7,9], endTime = [1,8,10]
輸出:7
解釋:
將?[0, 1]
?的會議安排到?[8, 9]
?,得到空余時間?[0, 7]
?。
示例 3:
輸入:eventTime = 10, startTime = [0,3,7,9], endTime = [1,4,8,10]
輸出:6
解釋:
將?[3, 4]
?的會議安排到?[8, 9]
?,得到空余時間?[1, 7]
?。
示例 4:
輸入:eventTime = 5, startTime = [0,1,2,3,4], endTime = [1,2,3,4,5]
輸出:0
解釋:
活動中的所有時間都被會議安排滿了。
提示:
1 <= eventTime <= 10^9
n == startTime.length == endTime.length
2 <= n <= 10^5
0 <= startTime[i] < endTime[i] <= eventTime
endTime[i] <= startTime[i + 1]
?其中?i
?在范圍?[0, n - 2]
?之間。
分析:首先預處理出每兩個會議之間的間隔。對于每一個會議,如果存在一個不是它左右會議的間隔時間大于它的持續時間,說明可以把這個會議移動到其它會議之間,從而使得它的前后會議之間間隔變大;如果不存在這樣的間隔時間,則把這個會議的開始時間設定為前一個會議的結束時間,計算間隔。
注意第一個會議和最后一個會議。第一個會議可以移動到最后一個會議的右邊,最后一個會議可以移動到第一個會議的左邊。
3439 是移動 k 個會議,但要保持相對順序;3440 則只能移動一個,但可以不考慮相對順序。兩道題都是貪心。
int cmp(const void *a,const void *b)
{return *(int*)a-*(int*)b;
}int maxFreeTime(int eventTime, int* startTime, int startTimeSize, int* endTime, int endTimeSize) {int ans=0,n=startTimeSize,t=0;int temp[n+5],interval[n+5],cnt[n+5];for(int i=1;i<n;++i)temp[i-1]=startTime[i]-endTime[i-1];qsort(temp,n-1,sizeof(int),cmp);interval[t]=temp[0];cnt[0]=1;int sum=1,flag=0;for(int i=1;i<=n-1;++i){if(temp[i]!=interval[t]||i==n-1)cnt[t++]=sum,interval[t]=temp[i],sum=1;else sum++;}// printf("t=%d\n",t);// for(int i=0;i<t;++i)// {// printf("interval=%d cnt=%d\n",interval[i],cnt[i]);// }for(int i=0;i<n;++i){if(!i){int last=endTime[0]-startTime[0],right=startTime[1]-endTime[0];ans=fmax(ans,startTime[1]-last);ans=fmax(ans,startTime[0]-0);bool flag=0;if(eventTime-endTime[n-1]>=last)flag=1;if(!flag){for(int j=t-1;j>=0;--j){if(interval[j]>=last){if(interval[j]!=right)flag=1;else if(interval[j]==right&&cnt[j]>1)flag=1;}if(flag)break;if(interval[j]<last)break;}}if(flag)ans=fmax(startTime[1],ans);// printf("i=%d flag=%d ans=%d\n",i,flag,ans);}else if(i==n-1){int last=endTime[n-1]-startTime[n-1],left=startTime[i]-endTime[i-1];ans=fmax(ans,eventTime-last-endTime[n-2]);ans=fmax(ans,eventTime-endTime[n-1]);bool flag=0;if(startTime[0]-0>=last)flag=1;if(!flag){for(int j=t-1;j>=0;--j){if(interval[j]>=last){if(interval[j]!=left)flag=1;else if(interval[j]==left&&cnt[j]>1)flag=1;}if(flag)break;if(interval[j]<last)break;}}if(flag)ans=fmax(eventTime-endTime[n-2],ans);// printf("i=%d flag=%d ans=%d\n",i,flag,ans);}else{int last=endTime[i]-startTime[i],left=startTime[i]-endTime[i-1],right=startTime[i+1]-endTime[i];int x=1;if(left==right)x=2;bool flag=0;for(int j=t-1;j>=0;--j){if(interval[j]>=last){if(interval[j]!=left&&right!=interval[j])flag=1;else if(interval[j]==left&&cnt[j]>x)flag=1;else if(interval[j]==right&&cnt[j]>x)flag=1;}if(flag)break;if(interval[j]<last)break;}if(!flag){if(eventTime-endTime[n-1]>=last||startTime[0]>=last)flag=1;}if(flag)ans=fmax(ans,startTime[i+1]-endTime[i-1]);else ans=fmax(ans,startTime[i+1]-endTime[i-1]-last);// printf("i=%d start=%d end=%d flag=%d ans=%d\n",i,startTime[i],endTime[i],flag,ans);}}return ans;
}