Problem
The purpose here is to find if there is a conflict in the given set of start and end times of the meeting time slots listed.
Input: Start and end times of meetings
Output: True / False for conflicts
package code.Misc;
import java.util.ArrayList;
public class Calendar {
static int time [] = new int[1440];
public static void main(String args[]){
String s[] = {"15:30","1:30","1:15","15:00"};
String e[] = {"18:35","13:28","1:30","15:29"};
System.out.println(scheduler(s, e));
}
public static int calculateMinute(int hour, int minute){
return hour*60+minute;
}
public static boolean timeClashChecker(int start, int end){
for(int i=start;i<=end;i++){
if(i==end){
time[i] = -1;
}
else if(time[i]==1){
return false;
}
else if(time[i]==-1){
time[i]=1;
}
else{
time[i]=1;
}
}
return true;
}
public static int parser(String time){
String [] timeParts = time.split(":");
int hour = Integer.parseInt(timeParts[0].trim());
int minute = Integer.parseInt(timeParts[1].trim());
return calculateMinute(hour,minute);
}
public static boolean scheduler(String start[], String end[]){
for(int i=0;i<start.length;i++){
int startMeeting = parser(start[i]);
int endMeeting = parser(end[i]);
boolean result = timeClashChecker(startMeeting,endMeeting);
if(result == false){ //clash check
return false;
}
}
return true;
}
}
Solution
A couple of things that would be good to point out:
-
It appears that your code only checks the clash between the start and end time. If the start time is always bigger than the end time, in theory it should never clash.
for(int i=0;i<start.length;i++){ int startMeeting = parser(start[i]); int endMeeting = parser(end[i]); boolean result = timeClashChecker(startMeeting,endMeeting); if(result == false){ //clash check return false; } }
might be replaced with:
for(int i=0;i<start.length;i++){ int startMeeting = parser(start[i]); int endMeeting = parser(end[i]); for(int e = 0; e < end.length; e++){ if(e == i) continue; int meetingEnd = parser(end[e]); if(meetingEnd > startMeeting && meetingEnd < endMeeting) return true; } for(int s = 0; s < start.length; s++){ if(s == i) continue; int meetingStart = parser(start[s]); if(meetingStart > startMeeting && meetingStart < endMeeting) return true; } }
This way the end of each meeting is checked with each starting time. If there is a clash with any of them, it should detect it. It also checks if each starting time of another is also between a meeting.
- If you make the change above, your timeClashChecker method is unnecessary.
- Some of the method names are not entirely helpful.
parser
could becomeparseTime
, andscheduler
could be changed todoesClash
, especially seeing it doesn’t do any of the scheduling itself.
Using model classes
It’s not easy to manage a pair of String
values to determine if the timings they represent overlap. You have to:
- Ensure both arrays are of the same length, and the values lined up,
- Interpret and validate the values (
parser(String)
pluscalculateMinute(int, int)
), - Deal with
int
values that you need to loop through, and finally - Require an intermediary
time[]
loop that stores… 1440 minutes in a day to record clashes.
Java 8 java.time.*
or Joda-Time
If you are on Java 8, there’s the java.time.*
APIs that you can use to model these times into nicer classes to work on. If you are not, you can still rely on Joda-Time for its selection of chronology-related classes.
For example, on Java 8, you can have a simple model class like:
public class TimeSlot {
private final LocalTime start;
private final LocalTime end;
public TimeSlot(LocalTime start, LocalTime end) {
// assuming we don't need additional validation here
this.start = start;
this.end = end;
}
// getters - getStart(), getEnd() - omitted for brevity
}
Then, given a List<TimeSlot>
, you can sort through them and compare the start and end times:
private static boolean hasClashes(Collection<TimeSlot> timeSlots) {
// materialize into another collection to not affect the input
List<TimeSlot> inputs = new ArrayList<>(timeSlots);
Collections.sort(inputs, Comparator.comparing(TimeSlot::getStart)
.thenComparing(TimeSlot::getEnd));
TimeSlot previous = inputs.get(0); // assuming at least one
for (int i = 1; i < inputs.size(); i++) {
TimeSlot current = inputs.get(i);
if (!current.getStart().isAfter(previous.getEnd())) {
return false;
} else {
previous = current;
}
}
return true;
}
sort()
using aComparator
that usesTimeSlot.getStart()
as a method reference for the first comparison,thenComparing()
the end time if twoTimeSlot
s have the same start time.- Loop through the sorted
List
and compare usingLocalTime.isAfter(LocalTime)
, which is easier to read and understand.