Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Given a list of date ranges, find a date which occurs maximum times

I have a list of Booking which contains startDate and endDate. I have to find the day which is the busiest in terms of bookings.

class Booking {
    Date startDate;
    Date endDate;
}

Example:

2016-10-12 to 2016-10-18
2016-10-11 to 2016-10-15
2016-10-13 to 2016-10-14
2016-10-12 to 2016-10-13

From these dates, it is obvious that 2016-10-13 was booked on all 4 times.

The solution that comes to my mind is:

  • iterate through all the dates from minimum startDate to maximum endDate in the list
  • keep a count of all number of bookings on all dates.
  • finally, return the date having maximum count.

But this is not the efficient solution. How can I find busiest day efficiently?

like image 899
Jainendra Avatar asked Feb 23 '17 15:02

Jainendra


People also ask

How do you check if a date is within a date range in Java?

We can use the simple isBefore , isAfter and isEqual to check if a date is within a certain date range; for example, the below program check if a LocalDate is within the January of 2020. startDate : 2020-01-01 endDate : 2020-01-31 testDate : 2020-01-01 testDate is within the date range.

How can I get a list of dates between two dates?

We can get the dates between two dates with single method call using the dedicated datesUntil method of a LocalDate class. The datesUntill returns the sequentially ordered Stream of dates starting from the date object whose method is called to the date given as method argument.


1 Answers

You can convert each Booking object as an interval in the number line, and then consider the problem as the problem of finding the point on the number line which is contained by maximum number of the intervals.

You can convert the date to number just by appending the year, month and day values, like this:

2016-10-12 -> 20161012

Then you can follow along this technique. Here is what I did, without the parts of converting the Date to int:

class Main {
    public static int findBusiest (int[] starts, int[] ends) {
        Arrays.sort(starts);
        Arrays.sort(ends);
        int n = starts.length;

        int in = 1, max = 1, time = starts[0];
        int i = 1, j = 0;

        while (i < n && j < n) {
            if (starts[i] <= ends[j]) {
                in++;

                if (in > max) {
                    max = in;
                    time = starts[i];
                }
                i++;
            }
            else {
                in--;
                j++;
            }
        }

        return time;
    }

    public static void main(String[] args) {

        int[] starts = { 20161012, 20161011, 20161013, 20161012 };
        int[] ends = { 20161018, 20161015, 20161014, 20161013 };

        System.out.println(findBusiest(starts, ends));
    }
}

Outputs:

20161013
like image 142
Sнаđошƒаӽ Avatar answered Sep 18 '22 22:09

Sнаđошƒаӽ