3453. Separate Squares I - Detailed Explanation

Free Coding Questions Catalog
Boost your coding skills with our essential coding questions catalog. Take a step towards a better tech career now!

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.

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
Design Gurus Team
-

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
Related Courses
Grokking the Coding Interview: Patterns for Coding Questions
Grokking the Coding Interview Patterns in Java, Python, JS, C++, C#, and Go. The most comprehensive course with 476 Lessons.
Grokking Modern AI Fundamentals
Master the fundamentals of AI today to lead the tech revolution of tomorrow.
Grokking Data Structures & Algorithms for Coding Interviews
Unlock Coding Interview Success: Dive Deep into Data Structures and Algorithms.
Image
One-Stop Portal For Tech Interviews.
Copyright © 2025 Design Gurus, LLC. All rights reserved.
;