Start learning free

LESSON 85 OF 347 · CONDITIONAL STATEMENTS - CHALLENGES

Interval Intersection in C#: O(1) Overlap Check

Practice Read the full explanation

Given two closed intervals [A1, B1] and [A2, B2], check and return if the two intervals intersect each other.

A closed interval [a, b] (with a <= b) denotes the set of real numbers x with a <= x <= b.

Two closed intervals are said to intersect if they have common numbers, i.e. that appear in both intervals.

Example 1:

Input: A1 = 1, B1 = 6, A2 = 3, B2 = 8
Output: true

Example 2:

Input: A1 = 1, B1 = 4, A2 = 4, B2 = 6
Output: true

Example 3:

Input: A1 = 1, B1 = 8, A2 = 4, B2 = 6
Output: true

Example 4:

Input: A1 = 4, B1 = 6, A2 = 1, B2 = 3
Output: false

Note:

Your algorithm should run in O(1) time and use O(1) extra space.


Hints:

Instead of thinking about when the intervals intersect each other, it's easier to think about when they do not intersect each other.

The intervals do not intersect each other when one of them is "to the left" of the other one i.e. B1 < A2 or B2 < A1.

We can write an if statement checking if B1 < A2 or B2 < A1. If so, we return false. Otherwise, we return true.

You can implement this using no else statements. You can even implement it in one line using only one return.

STEP 1 OF 1
    Ctrl + Enter to check

    C# · CONDITIONAL STATEMENTS - CHALLENGES

    Interval Intersection in C#, explained

    Problem overview

    The method Intersect takes the endpoints of two closed intervals, [A1, B1] and [A2, B2], and returns a bool: true when the intervals share at least one number, false otherwise. "Closed" means that both endpoints belong to the interval, so [1, 4] contains 1, 4 and everything between.

    Take the examples. [1, 6] and [3, 8] share the numbers 3 to 6, so the answer is true. [1, 4] and [4, 6] share exactly one number, 4, so the answer is true. [1, 8] contains [4, 6] completely, so the answer is true. [4, 6] and [1, 3] share nothing, so the answer is false.

    The lesson asks for O(1) time and space, which means no loops: a fixed number of comparisons.

    Approach: count the ways to miss

    Intervals can overlap in many ways: partly from the left, partly from the right, or with one inside the other. Listing all of them is tedious. Intervals can miss each other in only two ways, so describe those and negate:

    • The first interval ends before the second begins: B1 < A2.
    • The second interval ends before the first begins: B2 < A1.

    If neither of those holds, the intervals must overlap. This works because an interval is a single unbroken stretch: if one doesn't lie entirely to the left of the other, and doesn't lie entirely to the right, the two stretches must share a point.

    Step by step

    1. Write the "no overlap" condition. It is B1 < A2 || B2 < A1. Either one is enough to separate the intervals, so they are joined with ||.
    2. Use strict comparisons. The test is <, not <=. Intervals like [1, 4] and [4, 6] touch at 4, and since both are closed, they do intersect. Here B1 < A2 is 4 < 4, which is false.
    3. Negate the condition. Put the whole expression in parentheses and add ! in front. The method returns false if either "miss" condition holds and true otherwise. This takes a single return statement.

    The solution in C#

    class Solution {
        public bool Intersect(int A1, int B1, int A2, int B2) {
            return ! (B1 < A2 || B2 < A1);
        }
    }
    

    Some details about this code:

    • A bool expression can be returned directly. There is no need for if (...) { return false; } return true;, because the expression already evaluates to the answer.
    • The parentheses matter. ! applies to what comes right after it. Without the parentheses, it wouldn't cover the whole condition, and the code would fail to compile, since ! can't be applied to an int.
    • Parameter names. The lesson uses capitalised parameter names such as A1 and B1. C# allows that, and they must be spelled exactly as in the method signature.
    • The equivalent form. Negating the condition with De Morgan's laws gives B1 >= A2 && B2 >= A1. This version says "each interval ends at or after the start of the other", and it returns the same answers.

    Complexity

    Time: O(1). The method compares four integers in a fixed number of steps, whatever their values. The interval can be huge, but nothing loops over its numbers.

    Space: O(1). No collections or extra variables are created.

    Edge cases and common mistakes

    • Touching intervals. [1, 4] and [4, 6] intersect. Writing B1 <= A2 as a miss condition would wrongly report false.
    • One interval inside another. [1, 8] and [4, 6]: 8 < 4 is false and 6 < 1 is false, so the result is true.
    • Argument order. The method works the same when the intervals are swapped, because the two miss conditions are mirror images of each other. In the fourth example, B2 < A1 is 3 < 4, which is true, so the result is false.
    • Single-point intervals. [5, 5] and [5, 5] intersect, and the formula agrees: neither 5 < 5 is true.
    • Using && in the miss condition. Intervals miss each other if either condition holds. Joining the conditions with && would require both, which is impossible for valid intervals.

    Testing

    • Intersect(1, 6, 3, 8) gives true.
    • Intersect(1, 4, 4, 6) gives true.
    • Intersect(1, 8, 4, 6) gives true.
    • Intersect(4, 6, 1, 3) gives false.
    Keep going with C#About 340 step-by-step lessons, from your first line of code to coding interviews. Free to start.
    Start learning free