需求
今天有一个新需求
合并重复的时间段
栗子如下
时间段重叠,时间段重合,要整合成一条
入参就是多组时间
9:30-10:30
9:00-11:00
8:00-10:00
8:00-11:00
11:00-12:00
出参也是多个时间
8:00-11:00
11:00-12:00
到这里的话看到的伙伴可以想一想怎么实现
仔细想了一下,发现这和之前做过的一道贪心算法很像,合并区间问题,也有点像射箭那道题
头一次将刷到的算法用到业务中还有点小兴奋
至于思路的话
1.先把当前日期和时间和时间段分割后合并转时间戳,成为时间戳数组
2.添加到二维数组
3. 按排序,从小到大
4.遍历,判断区间右端点值与左端点值比较,合并区间,不断更新右边界
方案图如下
实现
@SpringBootTest
class Tests {
@Test
void contextLoads() {
String[] s = {
"9:30-10:30",
"9:00-11:00",
"8:00-10:00",
"8:00-11:00",
"11:00-12:00"
};
List<String> destArr = mergeDate(s);
System.out.println(destArr);
}
List<String> mergeDate(String[] arr) {
if (arr.length==0){
return new ArrayList<>();
}
LinkedList<Date[]> sourceList = new LinkedList<>();
for (String s : arr) {
Date startTm = null;
Date endTm = null;
try {
startTm = DateUtils.parseDate(DateFormatUtils.format(new Date(), "yyyy-MM-dd") + " " + s.split("-")[0], "yyyy-MM-dd HH:mm");
endTm = DateUtils.parseDate(DateFormatUtils.format(new Date(), "yyyy-MM-dd") + " " + s.split("-")[1], "yyyy-MM-dd HH:mm");
} catch (ParseException e) {
e.printStackTrace();
}
sourceList.add(new Date[]{startTm, endTm});
}
// 排序
Collections.sort(sourceList, (o1, o2) -> o1[0].compareTo(o2[0]));
LinkedList<Date[]> destList = new LinkedList<>();
destList.add(sourceList.get(0));
Date start;
Date end;
for (int i = 1; i < sourceList.size(); i++) {
//相等返回0,大于返回1,小于返回-1.
if (sourceList.get(i)[0].compareTo(destList.getLast()[1]) < 0) {
start = destList.getLast()[0];
end = sourceList.get(i)[1].compareTo(destList.getLast()[1]) > 0 ? sourceList.get(i)[1] : destList.getLast()[1];
destList.removeLast();
destList.add(new Date[]{start, end});
} else {
destList.add(sourceList.get(i));
}
}
ArrayList<String> destArr = new ArrayList<>();
for (Date[] d : destList) {
StringBuilder stringBuilder = new StringBuilder();
int index = 0;
for (Date date : d) {
stringBuilder.append(DateFormatUtils.format(date, "HH:mm"));
if (index == 0) {
stringBuilder.append("-");
}
index++;
}
destArr.add(stringBuilder.toString());
}
return destArr;
}
}