Bla*_*Hat 4 algorithm dynamic-programming greedy intervals
有人问我这个问题:
给你一个间隔清单.您必须设计一种算法来查找非重叠区间的序列,以便区间范围的总和最大.
例如:
如果给定的间隔是:
["06:00","08:30"],
["09:00","11:00"],
["08:00","09:00"],
["09:00","11:30"],
["10:30","14:00"],
["12:00","14:00"]
Run Code Online (Sandbox Code Playgroud)
三个间隔时范围最大化
[“06:00”, “08:30”],
[“09:00”, “11:30”],
[“12:00”, “14:00”],
Run Code Online (Sandbox Code Playgroud)
被选中.
因此,答案是420(分钟).
这是标准的间隔调度问题.
它可以通过使用动态编程来解决.
算法
让n间隔.在排序的间隔数组中sum[i]存储最大间隔的最大i间隔.算法如下
Sort the intervals in order of their end timings.
sum[0] = 0
For interval i from 1 to n in sorted array
j = interval in 1 to i-1 whose endtime is less than beginning time of interval i.
If j exist, then sum[i] = max(sum[j]+duration[i],sum[i-1])
else sum[i] = max(duration[i],sum[i-1])
Run Code Online (Sandbox Code Playgroud)
迭代用于n步骤,并且在每个步骤中,j可以使用二分搜索找到,即在log n时间上.因此算法需要O(n log n)时间.
public int longestNonOverLappingTI(TimeInterval[] tis){
Arrays.sort(tis);
int[] mt = new int[tis.length];
mt[0] = tis[0].getTime();
for(int j=1;j<tis.length;j++){
for(int i=0;i<j;i++){
int x = tis[j].overlaps(tis[i])?tis[j].getTime():mt[i] + tis[j].getTime();
mt[j] = Math.max(x,mt[j]);
}
}
return getMax(mt);
}
public class TimeInterval implements Comparable <TimeInterval> {
public int start;
public int end;
public TimeInterval(int start,int end){
this.start = start;
this.end = end;
}
public boolean overlaps(TimeInterval that){
return !(that.end < this.start || this.end < that.start);
}
public int getTime(){
return end - start;
}
@Override
public int compareTo(TimeInterval timeInterval) {
if(this.end < timeInterval.end)
return -1;
else if( this.end > timeInterval.end)
return 1;
else{
//end timeIntervals are same
if(this.start < timeInterval.start)
return -1;
else if(this.start > timeInterval.start)
return 1;
else
return 0;
}
}
}
Run Code Online (Sandbox Code Playgroud)
这是工作代码。基本上,由于有两个 for 循环,它的运行时间为 O(n^2)。但正如 Shashwat 所说,有一些方法可以让它在 O(n lg n) 内运行