问题描述
问题陈述
输入:每30分钟设置间隔(开始时间和结束时间)和每个元素的强度。
例如:
{00:00,01:30,5}
{01:00,02:30,10}
{00:30,02:30,2}
{01:00,04:00,3}
输出:最长30分钟重叠时间和重叠元素的强度总和。
对于上述输入,输出应为01:00-01:30且强度-20(此处的强度为直接总和,因为所有元素都完全参与了最大重叠30分钟,它可能会根据其中的参与时间而有所不同最大间隔)。
用简单的话来说,应该找到最大重叠的30分钟,以及在那个参与元素期间的附加强度。
可能看到不同的线程在回答最大重叠点和间隔,但是找不到上述解决方案。
任何建议都会有所帮助!
解决方法
算法如下:
- 定义起点(所有起点的最小值)和终点(所有终点的最大值)点以找到范围
- 将范围分成30分钟的子间隔
- 计算每个子间隔的总强度
- 查找具有最大计算强度的子间隔。
使用Java 8 Stream API和自定义类的实现示例(为方便起见,在几分钟内实现了起点和终点,而没有为简短起见就解析“ HH:MM”字符串)如下:
public class IntervalStrength {
private final int start; // inclusive
private final int end; // exclusive
private final int strength;
public IntervalStrength(int start,int end,int strength) {
this.start = start;
this.end = end;
this.strength = strength;
}
public int getStart() { return start; }
public int getEnd() { return end; }
public int getStrength() { return strength; }
public String toString() {
return String.format("[%02d:%02d,%02d:%02d] - %d",start / 60,start % 60,end / 60,end % 60,strength);
}
}
import java.util.*;
import java.util.stream.*;
public class Main {
private static final int HALF_HOUR = 30;
public static void main(String args[]) {
List<IntervalStrength> data = Arrays.asList(
new IntervalStrength(0,90,5),new IntervalStrength(60,150,10),new IntervalStrength(30,2),240,3)
);
int start = data.stream().mapToInt(IntervalStrength::getStart).min().getAsInt();
int end = data.stream().mapToInt(IntervalStrength::getEnd).max().getAsInt();
System.out.println(start + "," + end);
IntervalStrength strongest = IntStream
.iterate(start,t -> t < end - HALF_HOUR,t -> t + HALF_HOUR)
.mapToObj(t -> new IntervalStrength( // create sub-interval
t,t + HALF_HOUR,// start and end of sub-interval
data.stream() // find overlapping
.filter(d -> d.getStart() <= t && d.getEnd() >= t + HALF_HOUR)
.mapToInt(IntervalStrength::getStrength)
.sum() // calculate sum of strengths
))
// find max strength of sub-interval
.max(Comparator.comparingInt(IntervalStrength::getStrength))
.get(); // retrieve sub-interval
System.out.println(strongest);
}
}
输出:
0,240
[01:00,01:30] - 20
“无流”实现可能如下:
public static IntervalStrength findSubintervalMaxStrength(List<IntervalStrength> data) {
int start = Integer.MAX_VALUE,end = Integer.MIN_VALUE;
for (IntervalStrength interval : data) {
if (interval.getStart() < start) start = interval.getStart();
if (interval.getEnd() > end) end = interval.getEnd();
}
System.out.println(start + "," + end);
int maxStrength = 0;
int maxIntervalStart = start;
for (int t = start; t <= end - HALF_HOUR; t += HALF_HOUR) {
int subintervalStrength = 0;
for (IntervalStrength interval : data) {
if (interval.getStart() <= t && interval.getEnd() >= t + HALF_HOUR) {
subintervalStrength += interval.getStrength();
}
}
if (maxStrength < subintervalStrength) {
maxStrength = subintervalStrength;
maxIntervalStart = t;
}
}
return new IntervalStrength(maxIntervalStart,maxIntervalStart + HALF_HOUR,maxStrength);
}