从给定的日期范围列表中查找所有重叠的日期范围 [英] To find all the overlapping date ranges from a given list of Date Ranges
问题描述
我有一个BookingDateRange的列表,其中BookingDateRange是:
I have a List of BookingDateRange where BookingDateRange is :
public class BookingDateRange {
private Date fromDate;
private Date toDate;
//getters & setters of properties
}
要求:
- 我需要查找是否有任何日期重叠在BookingDate列表中说dateRangeList
- 如果是,查找所有日期范围对重叠表示字符串列表示overlapDatePairs
示例1 :
Input1:
dateRangeList [0] = 23 dec 2012- 27 dec 2012
dateRangeList[0] = 23 dec 2012- 27 dec 2012
dateRangeList [1] = 14 dec 2012 - 25 dec 2012
dateRangeList[1] = 14 dec 2012 - 25 dec 2012
dateRangeList [2] = 1 jan 2012 - 23 jan 2012
dateRangeList[2] = 1 jan 2012 - 23 jan 2012
Output1:
isOverlappingDates = true
isOverlappingDates = true
overlapDatePairs = [0_1]
overlappingDatePairs = [0_1]
示例2:
Input2:
dateRangeList [0] = 23 dec 2012- 27 dec 2012
dateRangeList[0] = 23 dec 2012- 27 dec 2012
dateRangeList [1] = 1 jan 2012 - 23 jan 2012
dateRangeList[1] = 1 jan 2012 - 23 jan 2012
Output2:
isOverlappingDates = false
isOverlappingDates = false
overlapDate Pairs = []
overlappingDatePairs = []
我的解决方案:
/**
* Checks if any of the dates overlap.
*
* @param dateRangeList the date range list
* @param overlappingDatePairs the overlapping date pairs where overlappingDatePair is stored in the format dateRange1_dateRange2
* @return true, if any of the dates overlap.
*/
public static boolean isOverlappingDates(
List<BookingDateRange> dateRangeList,
List<String> overlappingDatePairs) {
boolean isOverlap = false;
for (int index1 = 0; index1 < dateRangeList.size(); index1++) {
for (int index2 = index1 + 1; index2 < dateRangeList.size(); index2++) {
// Overlap exists if (StartA <= EndB) and (EndA >= StartB)
Date startA = dateRangeList.get(index1).getFromDate();
Date endA = dateRangeList.get(index1).getToDate();
Date startB = dateRangeList.get(index2).getFromDate();
Date endB = dateRangeList.get(index2).getToDate();
boolean isStartABeforeEndB = (startA.compareTo(endB)) < 0;
boolean isEndAAfterStartB = (endA.compareTo(startB)) > 0;
boolean isCurrentPairOverlap = false;
isCurrentPairOverlap = isStartABeforeEndB && isEndAAfterStartB;
if (isCurrentPairOverlap) {
overlappingDatePairs.add(index1 + "_" + index2);
isOverlap = true;
}
}
}
return isOverlap;
}
这种方法的复杂性是O(n ^ 2) 。是否有更好的复杂性?无法达到更复杂的算法。
The complexity of this approach is O(n ^2). Is a better complexity possible ? Could not arrive at an algorithm with a better complexity.
在SO中遇到了一些解决方案。但是没有一个可以完全满足要求。
Did come across a few solutions at SO. But none of them could cater to the requirement completely.
谢谢,
Shikha
Thanks, Shikha
推荐答案
这是O(nlog(n)),或者显然如果有很多碰撞,它是O(碰撞次数)。一个我曾经工作的公司使用类似于这个面试问题的东西。
Here's O(nlog(n)), or obviously if there are lots of collisions, it's O(number of collisions). A company I used to work for used something similar to this as an interview question.
private static class BookingTuple implements Comparable<BookingTuple> {
public final Date date;
public final boolean isStart;
public final int id;
public BookingTuple(Date date, boolean isStart, int id) {
this.date = date;
this.isStart = isStart;
this.id = id;
}
@Override
public int compareTo(BookingTuple other) {
int dateCompare = date.compareTo(other.date);
if (dateCompare != 0) {
return dateCompare;
} else {
if (!isStart && other.isStart) {
return -1;
} else if (isStart && !other.isStart) {
return 1;
} else {
return 0;
}
}
}
}
public static boolean isOverlappingDates(List<BookingDateRange> dateRangeList, List<String> overlappingDatePairs) {
List<BookingTuple> list = new ArrayList<BookingTuple>();
for (int i = 0; i < dateRangeList.size(); i++) {
Date from = dateRangeList.get(i).getFromDate();
Date to = dateRangeList.get(i).getToDate();
list.add(new BookingTuple(from, true, i));
list.add(new BookingTuple(to, false, i));
}
Collections.sort(list);
boolean overlap = false;
HashSet<Integer> active = new HashSet<Integer>();
for (BookingTuple tuple : list) {
if (!tuple.isStart) {
active.remove(tuple.id);
} else {
for (Integer n : active) {
overlappingDatePairs.add(n + "_" + tuple.id);
overlap = true;
}
active.add(tuple.id);
}
}
return overlap;
}
这篇关于从给定的日期范围列表中查找所有重叠的日期范围的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!