2446. Determine if Two Events Have Conflict
Problem Description
You are given two events that occur on the same day, represented as two arrays of strings:
event1 = [startTime1, endTime1]
event2 = [startTime2, endTime2]
Each time is given in 24-hour format as HH:MM
(e.g., "09:30", "14:45").
A conflict occurs when the two events have any overlapping time period - meaning there's at least one moment in time that belongs to both events.
Your task is to determine if these two events conflict with each other. Return true
if there is a conflict, and false
otherwise.
For example:
- If event1 is ["10:00", "11:00"] and event2 is ["10:30", "12:00"], they conflict because the time period from 10:30 to 11:00 is common to both events.
- If event1 is ["10:00", "11:00"] and event2 is ["11:30", "12:00"], they don't conflict because there's no overlapping time.
The solution checks for non-conflict conditions: if one event ends before the other starts (either event1[1] < event2[0]
or event1[0] > event2[1]
), there's no conflict. Otherwise, the events must overlap. Since string comparison works correctly with the HH:MM format, we can directly compare the time strings without converting them to numbers.
Intuition
When thinking about when two events conflict, it's often easier to first consider when they don't conflict. Two events can avoid conflict in only two ways:
- The first event ends completely before the second event starts
- The second event ends completely before the first event starts
If neither of these conditions is true, then the events must have some overlap.
Let's visualize this with a timeline. For events to NOT conflict:
- Either
event1
ends beforeevent2
starts:event1[1] < event2[0]
- Or
event2
ends beforeevent1
starts:event2[1] < event1[0]
(which is the same asevent1[0] > event2[1]
)
If we negate this logic, we get the condition for conflict:
not (event1[1] < event2[0] or event1[0] > event2[1])
A key insight here is that we can directly compare the time strings without converting them to minutes or any numerical format. This works because the HH:MM format ensures that string comparison preserves chronological order. For instance, "09:30" < "10:15" < "14:00" works correctly as string comparisons.
This approach elegantly handles all edge cases, including when events touch at their boundaries (like one ending at "10:00" and another starting at "10:00"), which is considered a conflict since they share that exact moment.
Solution Approach
The implementation uses a simple logical negation approach to determine if two events conflict.
The solution checks for the two non-conflicting scenarios:
event1[0] > event2[1]
: Event 1 starts after Event 2 endsevent1[1] < event2[0]
: Event 1 ends before Event 2 starts
The key steps in the implementation:
-
Direct String Comparison: Since the time format is
HH:MM
, we can directly compare the strings lexicographically. This works because:- Hours are zero-padded (e.g., "09:30" not "9:30")
- The format ensures chronological order matches alphabetical order
- "08:00" < "09:30" < "14:45" < "23:59" works correctly as string comparisons
-
Negation Logic: Instead of checking all possible overlap scenarios, we check for non-overlap and negate it:
return not (event1[0] > event2[1] or event1[1] < event2[0])
-
Boundary Cases: The solution correctly handles edge cases:
- When events touch exactly at a boundary point (e.g., one ends at "10:00" and another starts at "10:00"), the condition
event1[1] < event2[0]
is false, andevent1[0] > event2[1]
is also false, so the negation returnstrue
(conflict exists) - When events are completely disjoint with a gap between them, one of the conditions will be true, making the overall result
false
(no conflict)
- When events touch exactly at a boundary point (e.g., one ends at "10:00" and another starts at "10:00"), the condition
The visual representation from the reference helps understand this:
- If the events are positioned such that neither "completely before" condition is satisfied, they must overlap somewhere in the middle, indicating a conflict.
This approach has O(1) time complexity since we're only doing two string comparisons, and O(1) space complexity as no additional data structures are needed.
Ready to land your dream job?
Unlock your dream job with a 3-minute evaluator for a personalized learning plan!
Start EvaluatorExample Walkthrough
Let's walk through the solution with a concrete example to understand how the conflict detection works.
Example:
- event1 = ["09:30", "11:00"]
- event2 = ["10:30", "12:00"]
Step 1: Identify the conditions for non-conflict Two events DON'T conflict if:
- Condition A: event1 starts after event2 ends (
event1[0] > event2[1]
) - Condition B: event1 ends before event2 starts (
event1[1] < event2[0]
)
Step 2: Check Condition A Does event1 start after event2 ends?
- event1[0] = "09:30"
- event2[1] = "12:00"
- Is "09:30" > "12:00"? No (9:30 AM is before 12:00 PM)
Step 3: Check Condition B Does event1 end before event2 starts?
- event1[1] = "11:00"
- event2[0] = "10:30"
- Is "11:00" < "10:30"? No (11:00 AM is after 10:30 AM)
Step 4: Apply the negation logic Since neither non-conflict condition is true:
not (false or false)
=not false
= true
Therefore, the events do conflict.
Verification: Let's visualize the overlap on a timeline:
event1: [09:30 -------- 11:00] event2: [10:30 -------- 12:00] ^^^^^^ overlap from 10:30 to 11:00
The overlap period from 10:30 to 11:00 confirms our result - these events conflict!
Counter-example with no conflict: If event2 were ["11:30", "12:00"] instead:
- Condition A: Is "09:30" > "12:00"? No
- Condition B: Is "11:00" < "11:30"? Yes!
- Result:
not (false or true)
=not true
= false (no conflict)
This demonstrates how the algorithm correctly identifies both conflicting and non-conflicting events using simple string comparisons.
Solution Implementation
1from typing import List
2
3class Solution:
4 def haveConflict(self, event1: List[str], event2: List[str]) -> bool:
5 """
6 Determine if two events have a time conflict.
7
8 Args:
9 event1: List containing [start_time, end_time] as strings in "HH:MM" format
10 event2: List containing [start_time, end_time] as strings in "HH:MM" format
11
12 Returns:
13 bool: True if events overlap, False otherwise
14 """
15 # Two events DO NOT conflict if:
16 # 1. Event1 starts after event2 ends (event1[0] > event2[1])
17 # 2. Event1 ends before event2 starts (event1[1] < event2[0])
18 #
19 # Therefore, events HAVE a conflict when neither of these conditions is true
20 # Using De Morgan's law: not (A or B) = (not A) and (not B)
21 # Which means: events overlap when event1 doesn't start after event2 ends
22 # AND event1 doesn't end before event2 starts
23
24 return not (event1[0] > event2[1] or event1[1] < event2[0])
25
1class Solution {
2 /**
3 * Determines if two events have a time conflict.
4 * Each event is represented by a start and end time in "HH:MM" format.
5 *
6 * @param event1 Array containing start time [0] and end time [1] of first event
7 * @param event2 Array containing start time [0] and end time [1] of second event
8 * @return true if the events overlap, false otherwise
9 */
10 public boolean haveConflict(String[] event1, String[] event2) {
11 // Extract start and end times for better readability
12 String event1Start = event1[0];
13 String event1End = event1[1];
14 String event2Start = event2[0];
15 String event2End = event2[1];
16
17 // Two events do NOT conflict if:
18 // 1. Event1 starts after Event2 ends (event1Start > event2End), OR
19 // 2. Event1 ends before Event2 starts (event1End < event2Start)
20 //
21 // Therefore, events DO conflict when neither condition is true
22 boolean event1StartsAfterEvent2Ends = event1Start.compareTo(event2End) > 0;
23 boolean event1EndsBeforeEvent2Starts = event1End.compareTo(event2Start) < 0;
24
25 return !(event1StartsAfterEvent2Ends || event1EndsBeforeEvent2Starts);
26 }
27}
28
1class Solution {
2public:
3 bool haveConflict(vector<string>& event1, vector<string>& event2) {
4 // Two events have a conflict if they overlap in time
5 // Events do NOT conflict if:
6 // 1. event1 starts after event2 ends (event1[0] > event2[1])
7 // 2. event1 ends before event2 starts (event1[1] < event2[0])
8 // If neither condition is true, the events must overlap
9 return !(event1[0] > event2[1] || event1[1] < event2[0]);
10 }
11};
12
1/**
2 * Determines if two events have a time conflict
3 * @param event1 - First event with [startTime, endTime] in "HH:MM" format
4 * @param event2 - Second event with [startTime, endTime] in "HH:MM" format
5 * @returns true if the events overlap, false otherwise
6 */
7function haveConflict(event1: string[], event2: string[]): boolean {
8 // Two events don't conflict only when:
9 // 1. Event1 starts after Event2 ends (event1[0] > event2[1])
10 // 2. Event1 ends before Event2 starts (event1[1] < event2[0])
11 // If neither condition is true, the events overlap
12 return !(event1[0] > event2[1] || event1[1] < event2[0]);
13}
14
Time and Space Complexity
The time complexity is O(1)
because the algorithm performs a fixed number of operations regardless of input size. It only compares two pairs of strings (the start and end times of two events) using simple comparison operators. String comparison in this context is O(1)
since the time strings have a fixed format (HH:MM) with constant length.
The space complexity is O(1)
because the algorithm uses no additional data structures or variables that scale with input size. It only performs direct comparisons on the input parameters and returns a boolean result, requiring constant extra space.
Learn more about how to find time and space complexity quickly.
Common Pitfalls
1. Incorrect Boundary Handling - Treating Touch Points as Non-Conflicts
The Pitfall:
A common mistake is assuming that when two events touch exactly at their boundaries (one ends exactly when the other starts), they don't conflict. This leads to using >=
or <=
comparisons instead of >
or <
.
Incorrect Implementation:
def haveConflict(self, event1: List[str], event2: List[str]) -> bool:
# WRONG: Using >= and <= for boundary conditions
return not (event1[0] >= event2[1] or event1[1] <= event2[0])
Why It's Wrong:
- If event1 = ["10:00", "11:00"] and event2 = ["11:00", "12:00"]
- Using
event1[1] <= event2[0]
would evaluate to"11:00" <= "11:00"
= True - This would return
False
(no conflict), but the events DO conflict at exactly 11:00
The Fix:
Use strict comparisons (>
and <
) to ensure touching boundaries are considered conflicts:
def haveConflict(self, event1: List[str], event2: List[str]) -> bool:
return not (event1[0] > event2[1] or event1[1] < event2[0])
2. Attempting Time Conversion When String Comparison Suffices
The Pitfall: Unnecessarily converting time strings to minutes or other numeric formats, adding complexity and potential for bugs.
Overcomplicated Approach:
def haveConflict(self, event1: List[str], event2: List[str]) -> bool:
def timeToMinutes(time_str):
hours, minutes = map(int, time_str.split(':'))
return hours * 60 + minutes
start1 = timeToMinutes(event1[0])
end1 = timeToMinutes(event1[1])
start2 = timeToMinutes(event2[0])
end2 = timeToMinutes(event2[1])
return not (start1 > end2 or end1 < start2)
Why It's Unnecessary:
- The "HH:MM" format with zero-padding ensures lexicographic order matches chronological order
- String comparison is simpler, faster, and less error-prone
- No risk of conversion errors or edge cases with parsing
The Better Approach: Stick with direct string comparison as shown in the original solution.
3. Confusing the Logic - Double Negation Errors
The Pitfall: Getting confused with the negation logic and accidentally implementing the opposite condition.
Common Mistakes:
# WRONG: Forgetting the 'not'
def haveConflict(self, event1: List[str], event2: List[str]) -> bool:
return event1[0] > event2[1] or event1[1] < event2[0] # Returns True for NO conflict
# WRONG: Using 'and' instead of 'or'
def haveConflict(self, event1: List[str], event2: List[str]) -> bool:
return not (event1[0] > event2[1] and event1[1] < event2[0]) # Incorrect logic
How to Avoid:
- Remember: Check for non-overlap conditions with OR, then negate
- Test with simple examples: ["10:00", "11:00"] and ["10:30", "11:30"] should return True
- Think of it as: "Events conflict UNLESS one is completely before the other"
Given a sorted array of integers and an integer called target, find the element that
equals to the target and return its index. Select the correct code that fills the
___
in the given code snippet.
1def binary_search(arr, target):
2 left, right = 0, len(arr) - 1
3 while left ___ right:
4 mid = (left + right) // 2
5 if arr[mid] == target:
6 return mid
7 if arr[mid] < target:
8 ___ = mid + 1
9 else:
10 ___ = mid - 1
11 return -1
12
1public static int binarySearch(int[] arr, int target) {
2 int left = 0;
3 int right = arr.length - 1;
4
5 while (left ___ right) {
6 int mid = left + (right - left) / 2;
7 if (arr[mid] == target) return mid;
8 if (arr[mid] < target) {
9 ___ = mid + 1;
10 } else {
11 ___ = mid - 1;
12 }
13 }
14 return -1;
15}
16
1function binarySearch(arr, target) {
2 let left = 0;
3 let right = arr.length - 1;
4
5 while (left ___ right) {
6 let mid = left + Math.trunc((right - left) / 2);
7 if (arr[mid] == target) return mid;
8 if (arr[mid] < target) {
9 ___ = mid + 1;
10 } else {
11 ___ = mid - 1;
12 }
13 }
14 return -1;
15}
16
Recommended Readings
Coding Interview Patterns Your Personal Dijkstra's Algorithm to Landing Your Dream Job The goal of AlgoMonster is to help you get a job in the shortest amount of time possible in a data driven way We compiled datasets of tech interview problems and broke them down by patterns This way
Recursion Recursion is one of the most important concepts in computer science Simply speaking recursion is the process of a function calling itself Using a real life analogy imagine a scenario where you invite your friends to lunch https assets algo monster recursion jpg You first call Ben and ask
Runtime Overview When learning about algorithms and data structures you'll frequently encounter the term time complexity This concept is fundamental in computer science and offers insights into how long an algorithm takes to complete given a certain input size What is Time Complexity Time complexity represents the amount of time
Want a Structured Path to Master System Design Too? Don’t Miss This!