Learning pathsPricingA
← DSA problem library

DSA-038 · FOCUSED PRACTICE

Meeting Rooms — Conflict Detection

Intermediate · Java 21 · Version 1 · editorial draft

Java reference and baseline verified on JDK 21: 9342 deterministic checks. Learner drafts are not executed.

Understand the problem

Determine whether one person can attend every positive-duration meeting without a time conflict.

  • meetings is a non-null int[][] with 0–100,000 rows [start,end] of signed int times. Both methods throw IllegalArgumentException for null/malformed rows or start≥end. Zero-duration meetings are rejected rather than silently ignored.
  • Meetings occupy half-open [start,end). End at t and start at t are compatible; equal starts for two positive-duration meetings conflict. Empty and singleton valid inputs return true.
  • Return a boolean and preserve source outer order and row values. Sort a cloned outer array by start, reading rows without modification. No duration arithmetic or time-zone interpretation is involved; coordinates are ordered integer instants.

Examples

  1. Input: [[0,30],[5,10],[15,20]]
    Output: false

    The first long meeting conflicts with the meeting starting at five.

  2. Input: [[7,10],[2,4],[4,7]]
    Output: true

    Sorting gives a compatible chain; equal end/start boundaries do not overlap.

Before you start

  • Closed versus half-open intervals and compatible endpoints
  • Sorting with safe comparators and invariant or exchange proofs

Recognize the structure

This is a feasibility question about keeping every meeting. Sorting by start makes the first adjacent overlap sufficient to reject feasibility, and a conflict-free prefix makes checking the next adjacent pair sufficient to extend it.

Your Java attempt

Java 21 · Draft only. Your code is not compiled, executed, or graded here. Run it locally against the examples and edge cases.

Saving stores text in this browser, visible to other people using this browser profile. It does not sync to your account. Loading is always explicit.

No unsaved text changes · 145/20,000 characters

Self-review

Use the checklist to test your explanation. Checks apply to this visit.

Try before revealing

Hint 1

After sorting by start, where must the first conflict appear?

Hint 2

What does a conflict-free prefix tell you about all its earlier end times?

Hint 3

Reject an adjacent strict overlap; otherwise extend the compatible chain.

Derive the solution

Reveal the baseline, optimized reasoning, and Java code

Check every unordered pair

For each i<j, compare max(start[i],start[j]) with min(end[i],end[j]); a strict smaller start intersection means positive overlap. On [1,3) and [3,5), max starts equals min ends, so they are compatible. On [1,4) and [3,5), 3<4 proves a conflict. This O(n²) baseline needs constant other state.

Improve the baseline

Order meetings by start

Clone the outer array and sort with a safe start comparator. The input need not arrive in chronological order.

Compare each adjacent pair

For sorted current meeting i, reject if start[i]<end[i-1]. Equality is allowed because the earlier meeting releases its endpoint.

Extend a conflict-free prefix

If every tested adjacent pair is compatible, every earlier meeting ends no later than the next start in the chain, so the whole set is attendable.

Why it is correct

Sound conflict witness

If start[i]<end[i-1], sorted order gives start[i-1]≤start[i], and positive durations ensure the later meeting continues beyond its own start. The two adjacent intervals therefore share occupied time.

Conflict-free prefix induction

Initially one meeting is feasible. If the first i meetings are pairwise compatible in start order, their end/start chain is ordered. end[i-1]≤start[i] puts the new meeting after every earlier one, preserving global feasibility.

Completion and scope

Returning true after all adjacent checks proves all meetings fit, not just nearby ones. Returning false needs only one sound witness. Empty input has no pairs and is feasible; validation handles malformed or zero-duration rows first.

Complete Java reference and baseline

Save as Solution.java. Node definitions and imports are included where needed. The baseline is included for comparison; respect its input-size limits.

import java.util.*;
public final class Solution {
    private static void validate(int[][] meetings) {
        for (int[] row : meetings) if (row == null || row.length != 2 || row[0] >= row[1]) throw new IllegalArgumentException("positive-length half-open meetings required");
    }
    public static boolean canAttendMeetings(int[][] meetings) {
        validate(meetings);
        int[][] sorted = meetings.clone();
        Arrays.sort(sorted, Comparator.comparingInt(value -> value[0]));
        for (int i = 1; i < sorted.length; i++) if (sorted[i][0] < sorted[i - 1][1]) return false;
        return true;
    }
    public static boolean baseline(int[][] meetings) {
        validate(meetings);
        for (int i = 0; i < meetings.length; i++) for (int j = i + 1; j < meetings.length; j++)
            if (Math.max(meetings[i][0], meetings[j][0]) < Math.min(meetings[i][1], meetings[j][1])) return false;
        return true;
    }
}

Read the meaningful blocks

Strict overlap comparison

startCurrent<endPrevious rejects positive overlap; changing it to ≤ would reject legal back-to-back meetings.

Adjacent end is sufficient here

The algorithm returns immediately at the first conflict. It is not trying to continue a conflictful prefix using only the most recent end.

Sort a copy of references

No row values are changed, so cloning the outer order is enough to preserve the input for a scalar query.

Complexity

O(n log n) time and O(n) auxiliary space for the outer clone and object-sort workspace. The scan itself uses O(1) state and may stop at the first conflict.

The pairwise baseline costs O(n²) time and O(1) other workspace. If input is already guaranteed sorted, a separate streaming API can check adjacent meetings in O(n) time and O(1) state.

Exact-state walkthroughs

Reveal normal and boundary traces

An unsorted compatible chain

Input: [[7,10],[2,4],[4,7]] · Result: true

Step 1 of 4: Sort a copied order by start and initialize a feasible prefix.

Zero or one validated positive-duration meeting is trivially conflict-free.

Half-open meeting coordinates — end excluded
Exact interval endpoint orderFilled dots include endpoints; open right circles exclude them. Coordinates are spaced by their order, not by elapsed duration. Row numbers refer to the displayed order.#0#1#224710

Endpoint spacing is compressed to show coordinate order; bar lengths do not measure duration. Filled dots include an endpoint; an open right circle excludes it. Dashed vertical lines are fixed arrow positions.

  1. Row #0: [2, 4)
  2. Row #1: [4, 7)
  3. Row #2: [7, 10)
State after this step
VariableValue
intervalRows[[2,4],[4,7],[7,10]]
index-1
checkedThrough0
closedfalse
See the affected Java block
 1 import java.util.*;
 2 public final class Solution {
 3     private static void validate(int[][] meetings) {
 4         for (int[] row : meetings) if (row == null || row.length != 2 || row[0] >= row[1]) throw new IllegalArgumentException("positive-length half-open meetings required");
 5     }
 6     public static boolean canAttendMeetings(int[][] meetings) {
 7         validate(meetings);
 8         int[][] sorted = meetings.clone();
 9         Arrays.sort(sorted, Comparator.comparingInt(value -> value[0]));
10         for (int i = 1; i < sorted.length; i++) if (sorted[i][0] < sorted[i - 1][1]) return false;
11         return true;
12     }
13     public static boolean baseline(int[][] meetings) {
14         validate(meetings);
15         for (int i = 0; i < meetings.length; i++) for (int j = i + 1; j < meetings.length; j++)
16             if (Math.max(meetings[i][0], meetings[j][0]) < Math.min(meetings[i][1], meetings[j][1])) return false;
17         return true;
18     }
19 }
20 

Highlight locates the relevant statement or block; one trace step may summarize several assignments.

Read the full static trace
  1. Sort a copied order by start and initialize a feasible prefix.

    Zero or one validated positive-duration meeting is trivially conflict-free.

    intervalRows
    [[2,4],[4,7],[7,10]]
    index
    -1
    checkedThrough
    0
    closed
    false
  2. Extend the conflict-free start-ordered chain.

    The previous end is at most this start, so every earlier meeting also finishes in time.

    intervalRows
    [[2,4],[4,7],[7,10]]
    index
    1
    previousEnd
    4
    currentStart
    4
    conflict
    false
    checkedThrough
    1
    closed
    false
  3. Extend the conflict-free start-ordered chain.

    The previous end is at most this start, so every earlier meeting also finishes in time.

    intervalRows
    [[2,4],[4,7],[7,10]]
    index
    2
    previousEnd
    7
    currentStart
    7
    conflict
    false
    checkedThrough
    2
    closed
    false
  4. Return the contract result.

    The result satisfies the stated objective, endpoint policy, and input-preservation contract.

    result
    true

Containment gives an immediate conflict

Input: [[0,100],[1,2],[3,4]] · Result: false

Step 1 of 3: Sort a copied order by start and initialize a feasible prefix.

Zero or one validated positive-duration meeting is trivially conflict-free.

Half-open meeting coordinates — end excluded
Exact interval endpoint orderFilled dots include endpoints; open right circles exclude them. Coordinates are spaced by their order, not by elapsed duration. Row numbers refer to the displayed order.#0#1#201234100

Endpoint spacing is compressed to show coordinate order; bar lengths do not measure duration. Filled dots include an endpoint; an open right circle excludes it. Dashed vertical lines are fixed arrow positions.

  1. Row #0: [0, 100)
  2. Row #1: [1, 2)
  3. Row #2: [3, 4)
State after this step
VariableValue
intervalRows[[0,100],[1,2],[3,4]]
index-1
checkedThrough0
closedfalse
See the affected Java block
 1 import java.util.*;
 2 public final class Solution {
 3     private static void validate(int[][] meetings) {
 4         for (int[] row : meetings) if (row == null || row.length != 2 || row[0] >= row[1]) throw new IllegalArgumentException("positive-length half-open meetings required");
 5     }
 6     public static boolean canAttendMeetings(int[][] meetings) {
 7         validate(meetings);
 8         int[][] sorted = meetings.clone();
 9         Arrays.sort(sorted, Comparator.comparingInt(value -> value[0]));
10         for (int i = 1; i < sorted.length; i++) if (sorted[i][0] < sorted[i - 1][1]) return false;
11         return true;
12     }
13     public static boolean baseline(int[][] meetings) {
14         validate(meetings);
15         for (int i = 0; i < meetings.length; i++) for (int j = i + 1; j < meetings.length; j++)
16             if (Math.max(meetings[i][0], meetings[j][0]) < Math.min(meetings[i][1], meetings[j][1])) return false;
17         return true;
18     }
19 }
20 

Highlight locates the relevant statement or block; one trace step may summarize several assignments.

Read the full static trace
  1. Sort a copied order by start and initialize a feasible prefix.

    Zero or one validated positive-duration meeting is trivially conflict-free.

    intervalRows
    [[0,100],[1,2],[3,4]]
    index
    -1
    checkedThrough
    0
    closed
    false
  2. Reject a sound adjacent conflict witness.

    The two adjacent positive-duration intervals overlap.

    intervalRows
    [[0,100],[1,2],[3,4]]
    index
    1
    previousEnd
    100
    currentStart
    1
    conflict
    true
    checkedThrough
    0
    closed
    false
  3. Return the contract result.

    The result satisfies the stated objective, endpoint policy, and input-preservation contract.

    result
    false

Test the contract

  1. Input: []
    Output: true

    No conflicts.

  2. Input: [[1,5]]
    Output: true

    One valid meeting.

  3. Input: [[1,3],[1,2]]
    Output: false

    Equal starts overlap for positive durations.

  4. Input: [[2,2]]
    Output: IllegalArgumentException

    Zero-duration policy is explicit.

Common mistakes and counterexamples

Reject equality

Counterexample: [1,2) followed by [2,3) is attendable.

Use strict start<previousEnd for conflict.

Sort the caller array in place

Counterexample: The boolean result does not authorize reordering caller data.

Sort meetings.clone() and keep rows read-only.

Skip a conflict because a later short interval ends early

Counterexample: [0,100),[1,2),[3,4) already conflicts at the first pair.

Return at the first sound adjacent witness; do not reset feasibility afterward.

Follow-ups

Return a conflict witness.

Sort value/index records and return the two original meeting identities at the first conflict. Define whether any witness or the earliest chronological witness is required.

Check a sorted stream.

Keep only the previous end after validating each positive-duration record. The sorted-order precondition replaces in-memory sorting; reject an out-of-order stream if the API promises validation.

Count required rooms.

A boolean only distinguishes peak concurrency at most one from greater than one. To find the full resource requirement, track all active end times or sweep start/end events, as in the next lesson.

Related foundations

Keep practicing

AceYourInterviews · 2026-10-16 · Original teaching content, examples, and Java implementations authored for AceYourInterviews. These standard algorithmic tasks carry no company-frequency or interview-outcome claims.