836. Rectangle Overlap
Problem Description
You are given two axis-aligned rectangles represented as lists. Each rectangle is defined by four coordinates [x1, y1, x2, y2]
, where:
(x1, y1)
is the bottom-left corner(x2, y2)
is the top-right corner
The rectangles are axis-aligned, meaning:
- Top and bottom edges are parallel to the X-axis
- Left and right edges are parallel to the Y-axis
Your task is to determine if the two rectangles overlap. Two rectangles overlap when they share a common area (the intersection area is positive). Note that rectangles that only touch at corners or edges do NOT count as overlapping.
Given two rectangles rec1
and rec2
, return true
if they overlap, otherwise return false
.
The solution works by checking for non-overlapping conditions. Two rectangles do not overlap if:
- Rectangle 2 is completely above rectangle 1:
y3 >= y2
- Rectangle 2 is completely below rectangle 1:
y4 <= y1
- Rectangle 2 is completely to the right of rectangle 1:
x3 >= x2
- Rectangle 2 is completely to the left of rectangle 1:
x4 <= x1
If none of these conditions are true, the rectangles must overlap. The code returns the negation of these conditions combined with OR operators: not (y3 >= y2 or y4 <= y1 or x3 >= x2 or x4 <= x1)
.
Intuition
When thinking about whether two rectangles overlap, it's often easier to think about when they DON'T overlap. This is a common problem-solving technique - sometimes the complement of what we want is simpler to express.
Consider all the ways two rectangles can be positioned without overlapping:
- One rectangle can be completely to the left of the other
- One rectangle can be completely to the right of the other
- One rectangle can be completely above the other
- One rectangle can be completely below the other
If we can identify these non-overlapping cases, then any situation that doesn't fall into these categories must be an overlapping case.
Let's think about each non-overlapping scenario:
- Rectangle 2 is to the right of rectangle 1: This happens when the left edge of rectangle 2 (
x3
) is at or beyond the right edge of rectangle 1 (x2
), giving usx3 >= x2
- Rectangle 2 is to the left of rectangle 1: This happens when the right edge of rectangle 2 (
x4
) is at or to the left of the left edge of rectangle 1 (x1
), giving usx4 <= x1
- Rectangle 2 is above rectangle 1: This happens when the bottom edge of rectangle 2 (
y3
) is at or above the top edge of rectangle 1 (y2
), giving usy3 >= y2
- Rectangle 2 is below rectangle 1: This happens when the top edge of rectangle 2 (
y4
) is at or below the bottom edge of rectangle 1 (y1
), giving usy4 <= y1
If ANY of these conditions is true, the rectangles don't overlap. Therefore, rectangles overlap when NONE of these conditions are true, which we can express as: not (condition1 or condition2 or condition3 or condition4)
.
This negative logic approach is elegant because it reduces a potentially complex overlap calculation to just checking four simple boundary conditions.
Learn more about Math patterns.
Solution Approach
The implementation follows the non-overlap detection strategy identified in our intuition. We check for all cases where the rectangles don't overlap and negate the result.
First, we extract the coordinates from both rectangles:
- Rectangle 1:
(x1, y1, x2, y2)
where(x1, y1)
is bottom-left and(x2, y2)
is top-right - Rectangle 2:
(x3, y3, x4, y4)
where(x3, y3)
is bottom-left and(x4, y4)
is top-right
Next, we identify the four non-overlapping conditions:
- Rectangle 2 is above Rectangle 1:
y3 >= y2
- The bottom of rec2 is at or above the top of rec1
- Rectangle 2 is below Rectangle 1:
y4 <= y1
- The top of rec2 is at or below the bottom of rec1
- Rectangle 2 is to the right of Rectangle 1:
x3 >= x2
- The left edge of rec2 is at or beyond the right edge of rec1
- Rectangle 2 is to the left of Rectangle 1:
x4 <= x1
- The right edge of rec2 is at or to the left of the left edge of rec1
The key insight is that if ANY of these conditions is true, the rectangles don't overlap. We combine these conditions with the logical OR operator: (y3 >= y2 or y4 <= y1 or x3 >= x2 or x4 <= x1)
.
Finally, since we want to return true
when rectangles DO overlap, we negate the entire expression:
return not (y3 >= y2 or y4 <= y1 or x3 >= x2 or x4 <= x1)
This approach is efficient with O(1) time complexity and O(1) space complexity, as we only perform four comparisons without using any additional data structures.
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 two concrete examples to see how the non-overlapping conditions work.
Example 1: Overlapping Rectangles
- Rectangle 1:
[0, 0, 2, 2]
- a square from (0,0) to (2,2) - Rectangle 2:
[1, 1, 3, 3]
- a square from (1,1) to (3,3)
Let's extract the coordinates:
- rec1:
x1=0, y1=0, x2=2, y2=2
- rec2:
x3=1, y3=1, x4=3, y4=3
Now check each non-overlapping condition:
- Is rec2 above rec1?
y3 >= y2
→1 >= 2
→ False - Is rec2 below rec1?
y4 <= y1
→3 <= 0
→ False - Is rec2 to the right of rec1?
x3 >= x2
→1 >= 2
→ False - Is rec2 to the left of rec1?
x4 <= x1
→3 <= 0
→ False
Since all conditions are false: not (False or False or False or False)
= not False
= True
The rectangles overlap! They share the area from (1,1) to (2,2).
Example 2: Non-Overlapping Rectangles
- Rectangle 1:
[0, 0, 2, 2]
- a square from (0,0) to (2,2) - Rectangle 2:
[3, 0, 5, 2]
- a rectangle from (3,0) to (5,2)
Let's extract the coordinates:
- rec1:
x1=0, y1=0, x2=2, y2=2
- rec2:
x3=3, y3=0, x4=5, y4=2
Check each non-overlapping condition:
- Is rec2 above rec1?
y3 >= y2
→0 >= 2
→ False - Is rec2 below rec1?
y4 <= y1
→2 <= 0
→ False - Is rec2 to the right of rec1?
x3 >= x2
→3 >= 2
→ True ✓ - Is rec2 to the left of rec1?
x4 <= x1
→5 <= 0
→ False
Since at least one condition is true: not (False or False or True or False)
= not True
= False
The rectangles don't overlap! Rectangle 2 is completely to the right of rectangle 1 (there's a gap between x=2 and x=3).
This demonstrates how the algorithm correctly identifies both overlapping and non-overlapping cases by checking for separation conditions.
Solution Implementation
1from typing import List
2
3class Solution:
4 def isRectangleOverlap(self, rec1: List[int], rec2: List[int]) -> bool:
5 """
6 Determine if two rectangles overlap.
7
8 Args:
9 rec1: First rectangle represented as [x1, y1, x2, y2] where
10 (x1, y1) is bottom-left corner and (x2, y2) is top-right corner
11 rec2: Second rectangle represented as [x3, y3, x4, y4] where
12 (x3, y3) is bottom-left corner and (x4, y4) is top-right corner
13
14 Returns:
15 True if rectangles overlap, False otherwise
16 """
17 # Extract coordinates for first rectangle
18 x1, y1, x2, y2 = rec1
19
20 # Extract coordinates for second rectangle
21 x3, y3, x4, y4 = rec2
22
23 # Check if rectangles do NOT overlap:
24 # - rec2 is completely above rec1 (y3 >= y2)
25 # - rec2 is completely below rec1 (y4 <= y1)
26 # - rec2 is completely to the right of rec1 (x3 >= x2)
27 # - rec2 is completely to the left of rec1 (x4 <= x1)
28 # If none of these conditions are true, rectangles must overlap
29 return not (y3 >= y2 or y4 <= y1 or x3 >= x2 or x4 <= x1)
30
1class Solution {
2 /**
3 * Determines if two rectangles overlap.
4 * Each rectangle is represented by its bottom-left and top-right corners.
5 *
6 * @param rec1 First rectangle [x1, y1, x2, y2] where (x1, y1) is bottom-left and (x2, y2) is top-right
7 * @param rec2 Second rectangle [x3, y3, x4, y4] where (x3, y3) is bottom-left and (x4, y4) is top-right
8 * @return true if the rectangles overlap, false otherwise
9 */
10 public boolean isRectangleOverlap(int[] rec1, int[] rec2) {
11 // Extract coordinates for first rectangle
12 int leftX1 = rec1[0]; // Left x-coordinate of rectangle 1
13 int bottomY1 = rec1[1]; // Bottom y-coordinate of rectangle 1
14 int rightX1 = rec1[2]; // Right x-coordinate of rectangle 1
15 int topY1 = rec1[3]; // Top y-coordinate of rectangle 1
16
17 // Extract coordinates for second rectangle
18 int leftX2 = rec2[0]; // Left x-coordinate of rectangle 2
19 int bottomY2 = rec2[1]; // Bottom y-coordinate of rectangle 2
20 int rightX2 = rec2[2]; // Right x-coordinate of rectangle 2
21 int topY2 = rec2[3]; // Top y-coordinate of rectangle 2
22
23 // Check for non-overlapping conditions:
24 // 1. Rectangle 2's bottom is at or above rectangle 1's top (bottomY2 >= topY1)
25 // 2. Rectangle 2's top is at or below rectangle 1's bottom (topY2 <= bottomY1)
26 // 3. Rectangle 2's left is at or to the right of rectangle 1's right (leftX2 >= rightX1)
27 // 4. Rectangle 2's right is at or to the left of rectangle 1's left (rightX2 <= leftX1)
28 // If any of these conditions is true, rectangles don't overlap
29 return !(bottomY2 >= topY1 || topY2 <= bottomY1 || leftX2 >= rightX1 || rightX2 <= leftX1);
30 }
31}
32
1class Solution {
2public:
3 bool isRectangleOverlap(vector<int>& rec1, vector<int>& rec2) {
4 // Extract coordinates for first rectangle
5 // rec1[0], rec1[1] = bottom-left corner (x1, y1)
6 // rec1[2], rec1[3] = top-right corner (x2, y2)
7 int left1 = rec1[0];
8 int bottom1 = rec1[1];
9 int right1 = rec1[2];
10 int top1 = rec1[3];
11
12 // Extract coordinates for second rectangle
13 // rec2[0], rec2[1] = bottom-left corner (x3, y3)
14 // rec2[2], rec2[3] = top-right corner (x4, y4)
15 int left2 = rec2[0];
16 int bottom2 = rec2[1];
17 int right2 = rec2[2];
18 int top2 = rec2[3];
19
20 // Check for non-overlapping conditions:
21 // 1. bottom2 >= top1: rec2 is completely above rec1
22 // 2. top2 <= bottom1: rec2 is completely below rec1
23 // 3. left2 >= right1: rec2 is completely to the right of rec1
24 // 4. right2 <= left1: rec2 is completely to the left of rec1
25 // If any of these conditions is true, rectangles don't overlap
26 // Therefore, rectangles overlap when NONE of these conditions is true
27 return !(bottom2 >= top1 || top2 <= bottom1 || left2 >= right1 || right2 <= left1);
28 }
29};
30
1/**
2 * Determines if two rectangles overlap
3 * @param rec1 - First rectangle represented as [x1, y1, x2, y2] where (x1, y1) is bottom-left and (x2, y2) is top-right
4 * @param rec2 - Second rectangle represented as [x3, y3, x4, y4] where (x3, y3) is bottom-left and (x4, y4) is top-right
5 * @returns true if rectangles overlap, false otherwise
6 */
7function isRectangleOverlap(rec1: number[], rec2: number[]): boolean {
8 // Destructure coordinates from first rectangle
9 const [firstRectX1, firstRectY1, firstRectX2, firstRectY2] = rec1;
10
11 // Destructure coordinates from second rectangle
12 const [secondRectX1, secondRectY1, secondRectX2, secondRectY2] = rec2;
13
14 // Check for non-overlapping conditions:
15 // - Second rectangle is completely above first rectangle (secondRectY1 >= firstRectY2)
16 // - Second rectangle is completely below first rectangle (secondRectY2 <= firstRectY1)
17 // - Second rectangle is completely to the right of first rectangle (secondRectX1 >= firstRectX2)
18 // - Second rectangle is completely to the left of first rectangle (secondRectX2 <= firstRectX1)
19 // If none of these conditions are true, rectangles must overlap
20 return !(secondRectY1 >= firstRectY2 ||
21 secondRectY2 <= firstRectY1 ||
22 secondRectX1 >= firstRectX2 ||
23 secondRectX2 <= firstRectX1);
24}
25
Time and Space Complexity
The time complexity is O(1)
because the algorithm performs a fixed number of operations regardless of input size. It extracts 8 coordinate values from the two input lists and performs exactly 4 comparison operations (y3 >= y2
, y4 <= y1
, x3 >= x2
, x4 <= x1
) along with logical operations. Since all these operations take constant time, the overall time complexity is constant.
The space complexity is O(1)
because the algorithm only uses a fixed amount of extra space. It creates 8 variables (x1
, y1
, x2
, y2
, x3
, y3
, x4
, y4
) to store the coordinate values extracted from the input lists. The number of variables used does not depend on the input size, making the space complexity constant.
Learn more about how to find time and space complexity quickly.
Common Pitfalls
1. Confusing Edge-Touching with Overlapping
The Pitfall: A common mistake is misunderstanding the problem statement regarding edge-touching rectangles. The problem explicitly states that rectangles that only touch at corners or edges do NOT count as overlapping. However, developers might incorrectly use >
and <
operators instead of >=
and <=
, which would treat edge-touching rectangles as overlapping.
Incorrect Implementation:
# WRONG: This would consider edge-touching rectangles as overlapping return not (y3 > y2 or y4 < y1 or x3 > x2 or x4 < x1)
Why This Fails:
- When
rec1 = [0, 0, 2, 2]
andrec2 = [2, 0, 4, 2]
(rectangles share a vertical edge) - Using
x3 > x2
would evaluate to2 > 2 = False
- This would incorrectly return
True
(overlapping) when they should returnFalse
Correct Solution: Use >=
and <=
operators to properly exclude edge-touching cases:
return not (y3 >= y2 or y4 <= y1 or x3 >= x2 or x4 <= x1)
2. Incorrect Coordinate Assignment
The Pitfall: Assuming the wrong coordinate system or mixing up which corner is which. The problem states that (x1, y1)
is the bottom-left corner and (x2, y2)
is the top-right corner, but developers might accidentally treat them differently.
Common Mistakes:
- Treating
(x1, y1)
as top-left instead of bottom-left - Assuming
y1 > y2
(inverted y-axis) when actuallyy2 > y1
- Mixing up the coordinate indices when extracting from the list
Prevention: Always verify:
x1 < x2
(left edge is less than right edge)y1 < y2
(bottom edge is less than top edge)
3. Attempting to Calculate Intersection Area
The Pitfall: Over-engineering the solution by trying to calculate the actual intersection area when the problem only asks for a boolean result.
Inefficient Approach:
# Unnecessary complexity
intersection_width = min(x2, x4) - max(x1, x3)
intersection_height = min(y2, y4) - max(y1, y3)
return intersection_width > 0 and intersection_height > 0
Why The Simple Solution is Better:
- The non-overlap check is more intuitive and less error-prone
- It avoids potential issues with floating-point arithmetic
- It's more efficient with fewer operations
4. Forgetting to Negate the Result
The Pitfall: Since we're checking for non-overlapping conditions, forgetting the not
operator will return the opposite of what's expected.
Wrong:
# Returns True when rectangles DON'T overlap (opposite of desired behavior) return (y3 >= y2 or y4 <= y1 or x3 >= x2 or x4 <= x1)
Correct:
return not (y3 >= y2 or y4 <= y1 or x3 >= x2 or x4 <= x1)
Debugging Tip: Test with simple cases like [0,0,1,1]
and [0,0,1,1]
(identical rectangles) which should definitely return True
for overlap.
Which of the two traversal algorithms (BFS and DFS) can be used to find whether two nodes are connected?
Recommended Readings
Math for Technical Interviews How much math do I need to know for technical interviews The short answer is about high school level math Computer science is often associated with math and some universities even place their computer science department under the math faculty However the reality is that you
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
Want a Structured Path to Master System Design Too? Don’t Miss This!