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

  1. 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.
  2. As you raise Y, the area above the line decreases and the area below increases monotonically. That suggests a binary‑search on Y.
  3. 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

  1. Compute totalArea = ∑ lᵢ².
  2. Initialize low = min(yᵢ), high = max(yᵢ + lᵢ).
  3. 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
  4. Return low (or high).

Python Code

Python3
Python3

. . . .

Java Code

Java
Java

. . . .

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:

  1. Create events (yᵢ, +lᵢ) and (yᵢ+lᵢ, −lᵢ) for each square.
  2. Sort events by y.
  3. Maintain curSlope = 0, curY = events[0].y, accArea = 0, half = totalArea/2.
  4. For each event at y_k:
    • Let Δ = y_k − curY.
    • If accArea + curSlope·Δ ≥ half, solve
      y* = curY + (half − accArea) / curSlope
      
      and return y*.
    • Else update accArea += curSlope·Δ, curY = y_k, curSlope += event.weight.
  5. 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.
TAGS
leetcode
CONTRIBUTOR
Arslan Ahmad
Arslan Ahmad
ex-FAANG engineering manager and author or Grokking series.

GET YOUR FREE

Coding Questions Catalog

Design Gurus Newsletter - Latest from our Blog
Boost your coding skills with our essential coding questions catalog.
Take a step towards a better tech career now!
Explore Answers
347. Top K Frequent Elements - Detailed Explanation
Learn to solve Leetcode 347. Top K Frequent Elements with multiple approaches.
399. Evaluate Division - Detailed Explanation
Learn to solve Leetcode 399. Evaluate Division with multiple approaches.
176. Second Highest Salary - Detailed Explanation
Learn to solve Leetcode 176. Second Highest Salary with multiple approaches.
3161. Block Placement Queries - Detailed Explanation
Learn to solve Leetcode 3161. Block Placement Queries with multiple approaches.
322. Coin Change - Detailed Explanation
Learn to solve Leetcode 322. Coin Change with multiple approaches.
465. Optimal Account Balancing - Detailed Explanation
Learn to solve Leetcode 465. Optimal Account Balancing with multiple approaches.
Related Courses
New
Grokking the AI System Design Interview course cover
Grokking the AI System Design Interview
Learn to design AI systems the way interviewers expect: classic ML products, LLM and RAG architectures, and agentic systems, all through the lens of the system design interview.
4.6
(3,192 learners)
Discounted price for Your Region

$123

Grokking the Coding Interview: Patterns for Coding Questions course cover
Grokking the Coding Interview: Patterns for Coding Questions
The 24 essential patterns behind every coding interview question. Available in Java, Python, JavaScript, C++, C#, and Go. The most comprehensive coding interview course with 543 lessons. A smarter alternative to grinding LeetCode.
4.6
Discounted price for Your Region

$197

Grokking Modern AI Fundamentals course cover
Grokking Modern AI Fundamentals
Master the fundamentals of AI today to lead the tech revolution of tomorrow.
4.1
Discounted price for Your Region

$72

Design Gurus logo
One-Stop Portal For Tech Interviews.
Copyright © 2026 Design Gurus, LLC. All rights reserved.