Java Method Steps for Merging Several Time Intervals

  • 2021-08-21 20:19:54
  • OfStack

Causes of the problem

Suddenly, there is a scene at work, which needs to merge time intervals. Combining several closed time intervals, the realization idea is as follows:

1. First, sort the date intervals in chronological order, so that from1 of the last interval (denoted as next) must be no less than from of the first interval (denoted as prev).
2. For the next interval, assuming that next. from is greater than prev. to, it means that the two intervals are separated and a new interval should be added. Otherwise, it means that next. from is in [prev. from, prev. to]. At this time, it depends on whether next. to is greater than prev. to. If it is greater, the interval should be merged.

Concrete realization


  public static List<PeriodDto> mergePeriod(List<PeriodDto> periodList) {
    List<PeriodDto> result = new ArrayList<PeriodDto>();

    if (periodList == null || periodList.size() < 1) {
      return result;
    }

    //  Sort intervals 
    Collections.sort(periodList, new Comparator<PeriodDto>() {
      @Override
      public int compare(PeriodDto o1, PeriodDto o2) {
        if ((o1.getFrom().getTime() - o2.getFrom().getTime()) > 0) {
          return 1;
        } else if ((o1.getFrom().getTime() - o2.getFrom().getTime()) == 0) {
          return 0;
        } else {
          return -1;
        }
      }
    });
    PeriodDto prev = null;
    for (PeriodDto item : periodList) {
      if (prev == null || prev.getTo().before(item.getFrom())) {
        result.add(item);
        prev = item;
      } else if (prev.getTo().before(item.getTo())) {
        prev.setTo(item.getTo());
      }
    }

    return result;
  }

Write a test class to verify:


 public static void main(String[] args) throws ParseException {

    PeriodDto date1 = new PeriodDto();
    date1.setFrom(DateUtils.fmtDate("2020-01-01 12:00:00"));
    date1.setTo(DateUtils.fmtDate("2021-01-01 12:00:00"));
    
    PeriodDto date2 = new PeriodDto();
    date2.setFrom(DateUtils.fmtDate("2019-05-01 12:00:00"));
    date2.setTo(DateUtils.fmtDate("2020-04-29 12:00:00"));
    
    PeriodDto date3 = new PeriodDto();
    date3.setFrom(DateUtils.fmtDate("2018-01-01 12:00:00"));
    date3.setTo(DateUtils.fmtDate("2019-01-01 12:00:00"));
    
    PeriodDto date4 = new PeriodDto();
    date4.setFrom(DateUtils.fmtDate("2012-01-01 12:00:00"));
    date4.setTo(DateUtils.fmtDate("2023-01-01 12:00:00"));
    
    List<PeriodDto> list = new ArrayList<PeriodDto>();
    list.add(date1);
    list.add(date2);
    list.add(date3);
    list.add(date4);
    
    List<PeriodDto> result = mergePeriod(list);
    
    System.out.println(JSONObject.toJSONStringWithDateFormat(result, JSONObject.DEFFAULT_DATE_FORMAT));
  }

Run results:

[{"from":"2018-01-01 12:00:00","to":"2019-01-01 12:00:00"},{"from":"2019-05-01 12:00:00","to":"2021-01-01 12:00:00"},{"from":"2022-01-01 12:00:00","to":"2023-01-01 12:00:00"}]

OK, perfect call it a day and solve the problem.

PS: Supplementary sample

Given n intervals [li, ri], it is required to merge all intersections with intersection.

Note that if you intersect at the endpoints, there is also an intersection.

Output the number of intervals after merging.

For example, [1, 3] and [2, 6] can be merged into one interval [1, 6].

Input format
Line 1 contains the integer n.

Next, line n, each containing two integers l and r.

Output format
A total of 1 line, containing 1 integer, indicating the number of intervals after the merge interval is completed.

Data range
1 ≤ n ≤ 100000,
-109 ≤ li ≤ ri ≤ 109
Enter sample:
5
1 2
2 4
5 6
7 8
7 9
Sample output:
3

"Code:"


import java.io.*;
import java.util.*;

public class Main {

  static List<int[]> f = new ArrayList<>();

  public static void main(String[] args) throws IOException{
    BufferedReader read = new BufferedReader(new InputStreamReader(System.in));
    int n = Integer.parseInt(read.readLine());
    for(int i = 1; i <= n; i++) {
      String[] str = read.readLine().split(" ");
      int[] t = {Integer.parseInt(str[0]),Integer.parseInt(str[1])};
      f.add(t);
    }
    f.sort(new Comparator<int[]>(){
      public int compare(int[] o1, int[] o2){
        return o1[0] - o2[0];
      }
    });
    int ed = Integer.MIN_VALUE, res = 0;
    for (int[] t : f) {
      if(t[0] > ed) res ++;
      ed = Math.max(ed, t[1]);
    }
    System.out.println(res);
  }
}


Related articles: