Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/377.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 从给定的日期范围列表中查找所有重叠的日期范围_Java_Date - Fatal编程技术网

Java 从给定的日期范围列表中查找所有重叠的日期范围

Java 从给定的日期范围列表中查找所有重叠的日期范围,java,date,Java,Date,我有一个BookingDateRange列表,其中BookingDateRange是: public class BookingDateRange { private Date fromDate; private Date toDate; //getters & setters of properties } 要求: /** * Checks if any of the dates overlap. * * @par

我有一个BookingDateRange列表,其中BookingDateRange是:

    public class BookingDateRange {
        private Date fromDate;
        private Date toDate;

        //getters & setters of properties
   }
要求:

/**
 * 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;

    }
  • 我需要在BookingDate列表中查找是否有日期重叠,比如dateRangeList
  • 如果是,则查找所有重叠的日期范围对,例如字符串列表,例如重叠的日期对
  • 示例1

    输入1:

    日期范围列表[0]=2012年12月23日至2012年12月27日

    日期范围列表[1]=2012年12月14日至2012年12月25日

    日期范围列表[2]=2012年1月1日至2012年1月23日

    产出1:

    isOverlappingDates=真

    overlappingDatePairs=[0_1]

    示例2:

    /**
     * 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;
    
        }
    
    输入2:

    日期范围列表[0]=2012年12月23日至2012年12月27日

    日期范围列表[1]=2012年1月1日至2012年1月23日

    输出2:

    isOverlappingDates=false

    重叠日期对=[]

    我的解决方案:

    /**
     * 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;
    
        }
    
    /**
    *检查是否有任何日期重叠。
    *
    *@param dateRangeList日期范围列表
    *@param overlappingDatePairs重叠的日期对,其中overlappingDatePairs以dateRange1\u dateRange2格式存储
    *@return true,如果任何日期重叠。
    */
    公共静态布尔isOverlappingDates(
    列表日期范围列表,
    列表重叠(日期对){
    布尔值isOverlap=false;
    对于(int index1=0;index10;
    布尔值isCurrentPairOverlap=false;
    isCurrentPairOverlap=isstartabeforendb&isendaafterstart;
    如果(isCurrentPairOverlap){
    重叠日期对。添加(index1+“”+index2);
    isOverlap=真;
    }
    }
    }
    返回等重叠;
    }
    
    这种方法的复杂性是O(n^2)。是否可能有更好的复杂性?无法得到更复杂的算法

    当时确实遇到了一些解决方案。但没有一个能完全满足要求

    谢谢,
    Shikha

    我认为你不能做得更好,因为你必须将每个预订日期范围与其他日期范围进行比较

    因此,每个元素需要
    O(n)个比较
    ,而您有
    n个元素


    因此,我的解决方案将以复杂性换取内存。它假设日期的范围相对有限(不能将公元前5000年和公元6000年的日期混用)

    1创建
    地图

    2对于每个范围,选择第一个日期并将其转换为
    GregoriaCalendar
    。以“yyyy/MM/dd”(或类似格式)获取日期

    2a如果“yyyy/MM/dd”字符串已在映射中,请将新范围添加到列表中

    2b如果不是,则使用包含范围的新列表添加条目

    2c每天增加格里高利安达令。重复此操作,直到达到范围内的最后一个日期

    3对所有范围重复上述步骤

    4列出映射的键(如果使用“yyyy/MM/dd”格式,则排序很简单)。检查关联列表的大小。

    这里是O(nlog(n)),或者很明显,如果存在大量碰撞,则是O(碰撞数)。我曾经工作过的一家公司在面试中也提出了类似的问题

    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;
    }
    
    private静态类BookingTuple实现了可比较的{
    公开最终日期;
    公共服务启动;
    公共最终int id;
    public BookingTuple(日期、布尔值isStart、整数id){
    this.date=日期;
    this.isStart=isStart;
    this.id=id;
    }
    @凌驾
    公共整数比较(预订其他整数){
    int dateCompare=date.compareTo(其他.date);
    如果(日期比较!=0){
    返回日期比较;
    }否则{
    如果(!isStart&&other.isStart){
    返回-1;
    }else if(isStart&!other.isStart){
    返回1;
    }否则{
    返回0;
    }
    }
    }
    }
    公共静态布尔isOverlappingDates(列表日期范围列表、列表重叠日期对){
    列表=新的ArrayList();
    对于(int i=0;i
    看起来复杂性是O(n^2)而不是O(2^n)编辑的:D@gtgaxiola哎呀。。打字错误对O(n^2)。在问题中编辑。我没有检查
    O(n)
    声明,因此我正在考虑改进
    2^n
    复杂性(这意味着额外的开销通常没有意义)。看到gtgaxiola的修正,我的方法改进较少,但如果范围数较多且覆盖的日期较小,则仍然有用。按照您的逻辑,排序也有n^2的下限,这显然是不正确的。见公认的答案。