3453. Separate Squares I - Detailed Explanation
Problem Statement
You are given a 2D integer array squares
where each squares[i] = [xᵢ, yᵢ, lᵢ]
describes a square of side length lᵢ
whose bottom‑left corner is at (xᵢ, yᵢ)
. Find the minimum y‑coordinate Y
of a horizontal line such that the total area of all squares strictly above that line equals the total area of all squares strictly below that line. Answers within 10⁻⁵
of the true value are accepted. Squares may overlap, and overlapping regions are counted for each square independently.
Examples
Example 1
Input: squares = [[0,0,1],[2,2,1]]
Output: 1.00000
Explanation: Any line Y with 1 ≤ Y ≤ 2 splits one unit of area above and one unit below. The minimum is Y = 1.
Example 2
Input: squares = [[0,0,2],[1,1,1]]
Output: 1.16667
Explanation: Total area = 4 + 1 = 5. Half is 2.5.
For Y = 7/6 ≈ 1.16667:
• Square 1 at (0,0) of side 2 contributes
below: (7/6−0)*2 = 14/6 ≈ 2.33333
above: (2−7/6)*2 = 10/6 ≈ 1.66667
• Square 2 at (1,1) of side 1 contributes
below: (7/6−1)*1 = 1/6 ≈ 0.16667
above: (2−7/6−?)*1 = 5/6 ≈ 0.83333
Totals both 2.5 exactly.
Example 3
Input: squares = [[0,0,4]]
Output: 2.00000
Explanation: A single square of area 16 is split in half when Y = 2.
Constraints
1 ≤ squares.length ≤ 5·10⁴
squares[i].length == 3
0 ≤ xᵢ, yᵢ ≤ 10⁹
1 ≤ lᵢ ≤ 10⁹
- Sum of all
lᵢ·lᵢ
(total area) ≤ 10¹²
Hints
- For a fixed line at
Y
, you can compute in O(n) the total area above and below that line by iterating through all squares. - As you raise
Y
, the area above the line decreases and the area below increases monotonically. That suggests a binary‑search onY
. - Alternatively, view each square as contributing a “weight” of
lᵢ
to the vertical span[yᵢ, yᵢ+lᵢ]
. The area‐below function is then a piecewise‐linear integral of that weight; you can solve for the exact break‐point in one sweep.
Approach 1 Binary Search on Y
Explanation
Define for any candidate Y
:
areaAbove(Y) = ∑ᵢ { lᵢ², if Y ≤ yᵢ
0, if Y ≥ yᵢ+lᵢ
(yᵢ+lᵢ − Y)·lᵢ, otherwise }
areaBelow(Y) = ∑ᵢ { lᵢ², if Y ≥ yᵢ+lᵢ
0, if Y ≤ yᵢ
(Y − yᵢ)·lᵢ, otherwise }
We want areaAbove(Y) == areaBelow(Y)
. Let
diff(Y) = areaAbove(Y) − areaBelow(Y).
As Y
increases, areaAbove(Y)
decreases and areaBelow(Y)
increases, so diff(Y)
is strictly decreasing. We can binary‐search in the range
low = minᵢ yᵢ, high = maxᵢ (yᵢ + lᵢ)
to find the unique Y
where diff(Y) = 0
, within error ε = 10⁻⁶
.
Step‑by‑step Walkthrough
- Compute
totalArea = ∑ lᵢ²
. - Initialize
low = min(yᵢ)
,high = max(yᵢ + lᵢ)
. - Repeat ~60 times (enough for 10⁻⁵ accuracy):
mid = (low + high) / 2
- Evaluate
d = diff(mid)
- If
d > 0
(too much area above), move the line up:low = mid
- Else move down:
high = mid
- Return
low
(orhigh
).
Python Code
Java Code
Complexity Analysis
- Time O(n·log((maxY−minY)/ε)) ≈ O(n·60)
- Space O(1) extra
Approach 2 Sweep Line & Piecewise Integration
Explanation
Define the function
A(y) = areaBelow(y) = ∑ᵢ lᵢ · clamp(y − yᵢ, 0, lᵢ).
Its derivative w.r.t. y
is
A′(y) = ∑ᵢ lᵢ for y ∈ [yᵢ, yᵢ+lᵢ), else contribution 0.
So A(y)
grows piecewise‑linearly. To find y*
where A(y*) = totalArea/2
, do:
- Create events
(yᵢ, +lᵢ)
and(yᵢ+lᵢ, −lᵢ)
for each square. - Sort events by y.
- Maintain
curSlope = 0
,curY = events[0].y
,accArea = 0
,half = totalArea/2
. - For each event at
y_k
:- Let Δ =
y_k − curY
. - If
accArea + curSlope·Δ ≥ half
, solve
and returny* = curY + (half − accArea) / curSlope
y*
. - Else update
accArea += curSlope·Δ
,curY = y_k
,curSlope += event.weight
.
- Let Δ =
- The answer lies in some segment between events.
Complexity Analysis
- Time O(n log n) to sort + O(n) sweep
- Space O(n)
Common Mistakes
- Forgetting to count overlaps multiple times (each square independently).
- Mixing up which side of the line is “above” vs. “below.”
- Using too few binary‑search iterations and losing precision.
Edge Cases
- Single square → split at its vertical midpoint.
- All squares aligned with identical y‑ranges.
- Very large coordinates (use
double
).
Alternative Variations
- Splitting by x‑coordinate instead of y.
- Finding a line that maximizes difference rather than zeroing it.
- Splitting rectangles of various widths/heights.
Related Problems
GET YOUR FREE
Coding Questions Catalog