1401. Circle and Rectangle Overlapping
Problem Description
You are given a circle and a rectangle on a 2D plane. The circle is defined by its radius
and center coordinates (xCenter, yCenter)
. The rectangle is axis-aligned (its sides are parallel to the x and y axes) and defined by two corners: (x1, y1)
as the bottom-left corner and (x2, y2)
as the top-right corner.
Your task is to determine if the circle and rectangle overlap. They overlap if there exists at least one point that belongs to both the circle and the rectangle simultaneously. Points on the boundaries of both shapes are considered to be inside them.
Return true
if the circle and rectangle overlap, otherwise return false
.
For example, if a circle has radius 2 and center at (1, 1), and a rectangle has corners at (0, 0) and (3, 3), they would overlap because there are points that exist within both shapes. The key insight is to find the closest point on (or inside) the rectangle to the circle's center - if this distance is less than or equal to the radius, then the shapes overlap.
Intuition
To determine if a circle and rectangle overlap, we need to find if any point exists in both shapes. Instead of checking every point, we can think about this problem in reverse - what's the closest point on the rectangle to the circle's center?
If the closest point on the rectangle to the circle's center is within the radius distance, then the shapes must overlap. This transforms our problem into finding the minimum distance from the circle's center to any point on or inside the rectangle.
For any point inside or on the rectangle, its x-coordinate must be in the range [x1, x2]
and its y-coordinate must be in the range [y1, y2]
. To minimize the distance to the circle's center (xCenter, yCenter)
, we need to find the x and y coordinates that minimize |x - xCenter|
and |y - yCenter|
respectively.
For the x-coordinate:
- If
xCenter
falls within[x1, x2]
, the minimum distance in the x-direction is0
(we can choosex = xCenter
) - If
xCenter < x1
, the closest x-coordinate isx1
, giving distancex1 - xCenter
- If
xCenter > x2
, the closest x-coordinate isx2
, giving distancexCenter - x2
The same logic applies for the y-coordinate. Once we have the minimum distances in both directions (let's call them a
and b
), the closest point on the rectangle to the circle's center has distance sqrt(a² + b²)
from the center.
The circle and rectangle overlap if and only if this minimum distance is less than or equal to the radius, which gives us the condition: a² + b² ≤ radius²
.
Learn more about Math patterns.
Solution Approach
The implementation follows the mathematical approach we derived from the intuition. We need to find the minimum distance from the circle's center to the rectangle in both x and y directions.
We create a helper function f(i, j, k)
that computes the minimum distance from a point k
to an interval [i, j]
:
- If
i ≤ k ≤ j
, the point is within the interval, so the minimum distance is0
- If
k < i
, the point is to the left of the interval, so the minimum distance isi - k
- If
k > j
, the point is to the right of the interval, so the minimum distance isk - j
This function elegantly handles all three cases for finding the closest point on an interval to a given point.
In the main function:
- We calculate
a = f(x1, x2, xCenter)
- this gives us the minimum distance fromxCenter
to the x-interval[x1, x2]
- We calculate
b = f(y1, y2, yCenter)
- this gives us the minimum distance fromyCenter
to the y-interval[y1, y2]
- We check if
a² + b² ≤ radius²
The key insight is that a
and b
represent the x and y components of the shortest vector from the circle's center to the rectangle. If we were to draw a line from the circle's center to the closest point on the rectangle, a
would be the horizontal component and b
would be the vertical component of that line.
By using the Pythagorean theorem, a² + b²
gives us the square of the actual distance from the circle's center to the closest point on the rectangle. We compare this with radius²
(avoiding the square root calculation for efficiency) to determine if the shapes overlap.
The time complexity is O(1)
since we only perform constant-time arithmetic operations. The space complexity is also O(1)
as we only use a few variables.
Ready to land your dream job?
Unlock your dream job with a 5-minute evaluator for a personalized learning plan!
Start EvaluatorExample Walkthrough
Let's walk through an example with a circle centered at (4, 2) with radius 3, and a rectangle with bottom-left corner at (1, 0) and top-right corner at (3, 4).
Step 1: Find the minimum x-distance
- Circle's x-center: 4
- Rectangle's x-range: [1, 3]
- Since 4 > 3, the circle center is to the right of the rectangle
- Minimum x-distance: a = 4 - 3 = 1
Step 2: Find the minimum y-distance
- Circle's y-center: 2
- Rectangle's y-range: [0, 4]
- Since 0 ≤ 2 ≤ 4, the circle center's y-coordinate is within the rectangle's range
- Minimum y-distance: b = 0
Step 3: Check overlap condition
- We need to check if a² + b² ≤ radius²
- a² + b² = 1² + 0² = 1
- radius² = 3² = 9
- Since 1 ≤ 9, the condition is satisfied
Result: The circle and rectangle overlap (return true
)
To visualize: The closest point on the rectangle to the circle's center is (3, 2) - the right edge of the rectangle at the same y-coordinate as the circle's center. The distance from (4, 2) to (3, 2) is 1, which is less than the radius of 3, confirming the overlap.
Solution Implementation
1class Solution:
2 def checkOverlap(
3 self,
4 radius: int,
5 xCenter: int,
6 yCenter: int,
7 x1: int,
8 y1: int,
9 x2: int,
10 y2: int,
11 ) -> bool:
12 """
13 Check if a circle overlaps with an axis-aligned rectangle.
14
15 Args:
16 radius: Radius of the circle
17 xCenter: X-coordinate of the circle's center
18 yCenter: Y-coordinate of the circle's center
19 x1: X-coordinate of the rectangle's bottom-left corner
20 y1: Y-coordinate of the rectangle's bottom-left corner
21 x2: X-coordinate of the rectangle's top-right corner
22 y2: Y-coordinate of the rectangle's top-right corner
23
24 Returns:
25 True if the circle and rectangle overlap, False otherwise
26 """
27
28 def get_closest_distance_to_range(range_start: int, range_end: int, point: int) -> int:
29 """
30 Calculate the shortest distance from a point to a range [range_start, range_end].
31
32 If the point is within the range, the distance is 0.
33 If the point is outside the range, return the distance to the nearest boundary.
34
35 Args:
36 range_start: Start of the range (inclusive)
37 range_end: End of the range (inclusive)
38 point: The point to measure distance from
39
40 Returns:
41 The shortest distance from the point to the range
42 """
43 if range_start <= point <= range_end:
44 # Point is within the range
45 return 0
46
47 if point < range_start:
48 # Point is to the left/below the range
49 return range_start - point
50 else:
51 # Point is to the right/above the range
52 return point - range_end
53
54 # Calculate the closest horizontal distance from circle center to rectangle
55 horizontal_distance = get_closest_distance_to_range(x1, x2, xCenter)
56
57 # Calculate the closest vertical distance from circle center to rectangle
58 vertical_distance = get_closest_distance_to_range(y1, y2, yCenter)
59
60 # Check if the squared distance is within the squared radius
61 # Using squared values to avoid floating point operations
62 squared_distance = horizontal_distance ** 2 + vertical_distance ** 2
63 squared_radius = radius ** 2
64
65 return squared_distance <= squared_radius
66
1class Solution {
2 /**
3 * Checks if a circle overlaps with an axis-aligned rectangle.
4 *
5 * @param radius The radius of the circle
6 * @param xCenter The x-coordinate of the circle's center
7 * @param yCenter The y-coordinate of the circle's center
8 * @param x1 The x-coordinate of the rectangle's bottom-left corner
9 * @param y1 The y-coordinate of the rectangle's bottom-left corner
10 * @param x2 The x-coordinate of the rectangle's top-right corner
11 * @param y2 The y-coordinate of the rectangle's top-right corner
12 * @return true if the circle and rectangle overlap, false otherwise
13 */
14 public boolean checkOverlap(
15 int radius, int xCenter, int yCenter, int x1, int y1, int x2, int y2) {
16
17 // Calculate the closest distance from circle center to rectangle along x-axis
18 int closestXDistance = calculateDistanceToRange(x1, x2, xCenter);
19
20 // Calculate the closest distance from circle center to rectangle along y-axis
21 int closestYDistance = calculateDistanceToRange(y1, y2, yCenter);
22
23 // Check if the squared distance from circle center to closest point on rectangle
24 // is less than or equal to the squared radius (avoids square root calculation)
25 return closestXDistance * closestXDistance + closestYDistance * closestYDistance
26 <= radius * radius;
27 }
28
29 /**
30 * Calculates the minimum distance from a point to a range [rangeStart, rangeEnd].
31 *
32 * @param rangeStart The start of the range (inclusive)
33 * @param rangeEnd The end of the range (inclusive)
34 * @param point The point to measure distance from
35 * @return 0 if point is within the range, otherwise the distance to the nearest endpoint
36 */
37 private int calculateDistanceToRange(int rangeStart, int rangeEnd, int point) {
38 // If point is within the range, distance is 0
39 if (rangeStart <= point && point <= rangeEnd) {
40 return 0;
41 }
42
43 // If point is before the range, return distance to range start
44 // If point is after the range, return distance to range end
45 return point < rangeStart ? rangeStart - point : point - rangeEnd;
46 }
47}
48
1class Solution {
2public:
3 bool checkOverlap(int radius, int xCenter, int yCenter, int x1, int y1, int x2, int y2) {
4 // Lambda function to calculate the minimum distance from a point to a range
5 // If the point is within the range [minVal, maxVal], distance is 0
6 // Otherwise, return the distance to the nearest boundary
7 auto calculateDistanceToRange = [](int minVal, int maxVal, int point) -> int {
8 if (minVal <= point && point <= maxVal) {
9 return 0; // Point is within the range
10 }
11 // Point is outside the range, find distance to nearest boundary
12 return point < minVal ? minVal - point : point - maxVal;
13 };
14
15 // Calculate horizontal distance from circle center to rectangle
16 // Rectangle's x-range is [x1, x2]
17 int horizontalDistance = calculateDistanceToRange(x1, x2, xCenter);
18
19 // Calculate vertical distance from circle center to rectangle
20 // Rectangle's y-range is [y1, y2]
21 int verticalDistance = calculateDistanceToRange(y1, y2, yCenter);
22
23 // Check if the squared distance from circle center to rectangle is within radius
24 // Using squared values to avoid floating point calculations
25 return horizontalDistance * horizontalDistance + verticalDistance * verticalDistance <= radius * radius;
26 }
27};
28
1/**
2 * Checks if a circle overlaps with an axis-aligned rectangle
3 * @param radius - The radius of the circle
4 * @param xCenter - The x-coordinate of the circle's center
5 * @param yCenter - The y-coordinate of the circle's center
6 * @param x1 - The x-coordinate of the bottom-left corner of the rectangle
7 * @param y1 - The y-coordinate of the bottom-left corner of the rectangle
8 * @param x2 - The x-coordinate of the top-right corner of the rectangle
9 * @param y2 - The y-coordinate of the top-right corner of the rectangle
10 * @returns true if the circle and rectangle overlap, false otherwise
11 */
12function checkOverlap(
13 radius: number,
14 xCenter: number,
15 yCenter: number,
16 x1: number,
17 y1: number,
18 x2: number,
19 y2: number,
20): boolean {
21 /**
22 * Calculates the minimum distance from a point to a line segment
23 * @param segmentStart - Start coordinate of the line segment
24 * @param segmentEnd - End coordinate of the line segment
25 * @param point - The point coordinate to measure distance from
26 * @returns The minimum distance from the point to the segment
27 */
28 const getMinimumDistanceToSegment = (
29 segmentStart: number,
30 segmentEnd: number,
31 point: number
32 ): number => {
33 // If the point is within the segment bounds, distance is 0
34 if (segmentStart <= point && point <= segmentEnd) {
35 return 0;
36 }
37 // If point is before segment start, return distance to start
38 // If point is after segment end, return distance to end
39 return point < segmentStart ? segmentStart - point : point - segmentEnd;
40 };
41
42 // Calculate minimum horizontal distance from circle center to rectangle
43 const horizontalDistance: number = getMinimumDistanceToSegment(x1, x2, xCenter);
44
45 // Calculate minimum vertical distance from circle center to rectangle
46 const verticalDistance: number = getMinimumDistanceToSegment(y1, y2, yCenter);
47
48 // Check if the squared distance is within the squared radius
49 // Using squared values to avoid computing square root
50 return horizontalDistance * horizontalDistance + verticalDistance * verticalDistance <= radius * radius;
51}
52
Time and Space Complexity
Time Complexity: O(1)
The algorithm performs a constant number of operations regardless of input size:
- The helper function
f
is called exactly twice (once for x-coordinate and once for y-coordinate) - Each call to
f
performs at most 2 comparisons and 1 arithmetic operation - The final calculation involves 2 multiplications, 1 addition, and 1 comparison
- All operations are basic arithmetic/comparison operations that take constant time
Therefore, the overall time complexity is O(1)
.
Space Complexity: O(1)
The algorithm uses only a fixed amount of extra space:
- Two integer variables
a
andb
to store the results of functionf
- No additional data structures are created
- The helper function
f
uses only its parameters and doesn't allocate any extra space - The space usage doesn't depend on the input size
Therefore, the overall space complexity is O(1)
.
Learn more about how to find time and space complexity quickly.
Common Pitfalls
1. Incorrectly Calculating Distance When Circle Center is Inside Rectangle
Pitfall: A common mistake is to assume that if the circle's center is inside the rectangle, we need to check distances to all four edges or corners. This leads to unnecessary complexity and potential errors.
Why it happens: Developers might overthink the problem and try to handle the "center inside rectangle" case separately with complex edge/corner checking logic.
Correct approach: The solution elegantly handles this case automatically. When the circle center is inside the rectangle, both horizontal_distance
and vertical_distance
become 0 (since the center's coordinates fall within both ranges). This results in squared_distance = 0
, which is always ≤ radius²
, correctly returning true
.
2. Using Euclidean Distance to Rectangle Edges Instead of Closest Point
Pitfall: Calculating the distance from the circle center to each of the four edges of the rectangle and taking the minimum, which doesn't account for corner cases correctly.
# INCORRECT approach
def checkOverlap_wrong(self, radius, xCenter, yCenter, x1, y1, x2, y2):
# This incorrectly calculates distances to edges
dist_to_left = abs(xCenter - x1)
dist_to_right = abs(xCenter - x2)
dist_to_bottom = abs(yCenter - y1)
dist_to_top = abs(yCenter - y2)
min_dist = min(dist_to_left, dist_to_right, dist_to_bottom, dist_to_top)
return min_dist <= radius # WRONG!
Why it's wrong: This approach fails when the closest point to the circle center is a corner of the rectangle. For example, if the circle center is diagonally away from a corner, the actual distance should be calculated using both x and y components, not just the minimum of individual edge distances.
Solution: The correct approach finds the closest point on the rectangle (which could be on an edge, at a corner, or inside if the center is within the rectangle) by independently finding the closest x-coordinate and y-coordinate, then combining them using the Pythagorean theorem.
3. Floating Point Precision Issues with Square Root
Pitfall: Using square root operations and comparing floating-point numbers:
# RISKY approach due to floating point precision
import math
def checkOverlap_risky(self, radius, xCenter, yCenter, x1, y1, x2, y2):
# ... calculate horizontal_distance and vertical_distance ...
actual_distance = math.sqrt(horizontal_distance ** 2 + vertical_distance ** 2)
return actual_distance <= radius # Potential precision issues!
Why it's problematic: Floating-point arithmetic can introduce rounding errors, especially with square root operations. This might cause edge cases where shapes that barely touch to be incorrectly classified.
Solution: The provided solution avoids this by comparing squared values (squared_distance <= squared_radius
), which keeps all calculations in integer arithmetic (assuming integer inputs) and avoids precision issues entirely.
Which algorithm should you use to find a node that is close to the root of the tree?
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!