Skip to content

Commit 91d3f12

Browse files
chore: add LeetCode daily solution
1 parent 412c167 commit 91d3f12

5 files changed

Lines changed: 193 additions & 0 deletions

File tree

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
# Separate Squares I (Medium)
2+
3+
**Problem ID:** 3453
4+
**Date:** 2026-01-13
5+
**Link:** https://leetcode.com/problems/separate-squares-i/
6+
7+
## Approach
8+
9+
To solve the problem of finding the minimum y-coordinate value of a horizontal line that separates the total area of squares above and below it, we can follow a systematic approach:
10+
11+
### Main Idea:
12+
The key idea is to utilize a binary search combined with a sweep line technique to efficiently compute the areas above and below a potential horizontal line at various y-coordinates. The goal is to find a y-coordinate where the areas are equal.
13+
14+
### Approach:
15+
1. **Calculate Total Area**: First, calculate the total area of all squares. This will help in determining the target area for both above and below the line.
16+
17+
2. **Binary Search Setup**: Since the y-coordinates can range significantly (up to \(10^9\)), we can use binary search to efficiently find the y-coordinate. Set the initial search bounds from 0 to the maximum y-coordinate of the squares plus their side lengths.
18+
19+
3. **Area Calculation Function**: For a given y-coordinate (midpoint in binary search), compute the areas above and below the line:
20+
- For each square, determine the portion of its area that lies above and below the line. This can be done by checking the square's y-coordinate and its height against the current midpoint.
21+
- Accumulate the areas for all squares to get the total area above and below the line.
22+
23+
4. **Adjust Binary Search**: Compare the areas:
24+
- If the area above the line is greater than the area below, move the search to lower y-coordinates (i.e., adjust the upper bound).
25+
- If the area below is greater, move to higher y-coordinates (i.e., adjust the lower bound).
26+
- Continue this process until the search converges to a point where the areas are approximately equal (within the specified tolerance).
27+
28+
5. **Precision Handling**: Since the problem requires the answer to be accurate within \(10^{-5}\), ensure that the binary search continues until the difference between the lower and upper bounds is less than this threshold.
29+
30+
### Data Structures:
31+
- A simple list or array to store the squares and their properties (coordinates and side lengths).
32+
- Variables to track the total area and the areas above and below the line during calculations.
33+
34+
### Complexity:
35+
- The binary search will run in \(O(\log(\text{max\_y}))\), where \(\text{max\_y}\) is the maximum y-coordinate considered.
36+
- For each midpoint in the binary search, calculating the areas involves iterating through all squares, which takes \(O(n)\), where \(n\) is the number of squares.
37+
- Therefore, the overall time complexity is \(O(n \log(\text{max\_y}))\).
38+
39+
This approach efficiently narrows down the potential y-coordinate while ensuring that we accurately compute the areas, handling overlaps as specified in the problem statement.
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
import java.util.*;
2+
3+
public class Solution {
4+
public double findMedianHeight(int[][] squares) {
5+
List<Double> heights = new ArrayList<>();
6+
for (int[] square : squares) {
7+
int x = square[0], y = square[1], l = square[2];
8+
heights.add((double) y);
9+
heights.add((double) (y + l));
10+
}
11+
12+
Collections.sort(heights);
13+
double totalArea = 0;
14+
for (int[] square : squares) {
15+
totalArea += Math.pow(square[2], 2);
16+
}
17+
18+
double halfArea = totalArea / 2;
19+
double areaAbove = 0, areaBelow = 0;
20+
double lastHeight = heights.get(0);
21+
22+
for (double height : heights) {
23+
if (height == lastHeight) continue;
24+
double width = height - lastHeight;
25+
areaBelow += calculateArea(squares, lastHeight, height, true);
26+
areaAbove += calculateArea(squares, lastHeight, height, false);
27+
28+
if (areaAbove >= halfArea) {
29+
return lastHeight + (halfArea - areaBelow) / (areaAbove - areaBelow) * width;
30+
}
31+
lastHeight = height;
32+
}
33+
34+
return lastHeight;
35+
}
36+
37+
private double calculateArea(int[][] squares, double line, double nextLine, boolean below) {
38+
double area = 0;
39+
for (int[] square : squares) {
40+
int x = square[0], y = square[1], l = square[2];
41+
if (below) {
42+
if (y < line) {
43+
area += Math.min(nextLine, y + l) - line > 0 ? (Math.min(nextLine, y + l) - line) * l : 0;
44+
}
45+
} else {
46+
if (y + l > line) {
47+
area += Math.min(nextLine, y + l) - line > 0 ? (Math.min(nextLine, y + l) - line) * l : 0;
48+
}
49+
}
50+
}
51+
return area;
52+
}
53+
}
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
class Solution {
2+
minY(squares) {
3+
const events = [];
4+
const totalArea = squares.reduce((acc, [x, y, l]) => {
5+
events.push([x, y, y + l, 1]);
6+
events.push([x + l, y, y + l, -1]);
7+
return acc + l * l;
8+
}, 0);
9+
10+
events.sort((a, b) => a[0] - b[0] || a[1] - b[1]);
11+
12+
let currentArea = 0;
13+
let lastX = events[0][0];
14+
const heightCount = new Map();
15+
16+
const addHeight = (y1, y2) => {
17+
for (let y = y1; y < y2; y++) {
18+
heightCount.set(y, (heightCount.get(y) || 0) + 1);
19+
}
20+
};
21+
22+
const removeHeight = (y1, y2) => {
23+
for (let y = y1; y < y2; y++) {
24+
if (heightCount.has(y)) {
25+
heightCount.set(y, heightCount.get(y) - 1);
26+
if (heightCount.get(y) === 0) {
27+
heightCount.delete(y);
28+
}
29+
}
30+
}
31+
};
32+
33+
for (const [x, y1, y2, type] of events) {
34+
const width = x - lastX;
35+
if (width > 0) {
36+
const heights = Array.from(heightCount.keys()).sort((a, b) => a - b);
37+
let areaAbove = 0;
38+
let areaBelow = 0;
39+
let lastHeight = 0;
40+
41+
for (const height of heights) {
42+
const heightWidth = height - lastHeight;
43+
if (heightWidth > 0) {
44+
areaBelow += heightWidth * width;
45+
}
46+
lastHeight = height;
47+
}
48+
49+
areaAbove = totalArea - areaBelow;
50+
51+
if (Math.abs(areaAbove - areaBelow) < 1e-5) {
52+
return (areaAbove + areaBelow) / (2 * width);
53+
}
54+
}
55+
56+
if (type === 1) {
57+
addHeight(y1, y2);
58+
} else {
59+
removeHeight(y1, y2);
60+
}
61+
62+
lastX = x;
63+
}
64+
65+
return -1; // Should not reach here
66+
}
67+
}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
class Solution:
2+
def separateSquares(self, squares: List[List[int]]) -> float:
3+
events = []
4+
total_area = 0
5+
6+
for x, y, l in squares:
7+
events.append((y, l, 1)) # start of square
8+
events.append((y + l, l, -1)) # end of square
9+
total_area += l * l
10+
11+
events.sort()
12+
13+
below_area = 0
14+
above_area = total_area
15+
last_y = events[0][0]
16+
17+
for y, l, typ in events:
18+
if below_area == above_area:
19+
return last_y
20+
21+
height = y - last_y
22+
if height > 0:
23+
below_area += height * (above_area - below_area)
24+
25+
if typ == 1:
26+
below_area += l * l
27+
else:
28+
below_area -= l * l
29+
30+
above_area = total_area - below_area
31+
last_y = y
32+
33+
return last_y

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -332,3 +332,4 @@ Through completing the Blind 75 and NeetCode 150, you will have mastered:
332332
- 2026-01-08 — [Max Dot Product of Two Subsequences](https://leetcode.com/problems/max-dot-product-of-two-subsequences/) (Hard) → `Hard/2026-01-08-1458-Max-Dot-Product-of-Two-Subsequences`
333333
- 2026-01-11 — [Maximal Rectangle](https://leetcode.com/problems/maximal-rectangle/) (Hard) → `Hard/2026-01-11-85-Maximal-Rectangle`
334334
- 2026-01-12 — [Minimum Time Visiting All Points](https://leetcode.com/problems/minimum-time-visiting-all-points/) (Easy) → `Easy/2026-01-12-1266-Minimum-Time-Visiting-All-Points`
335+
- 2026-01-13 — [Separate Squares I](https://leetcode.com/problems/separate-squares-i/) (Medium) → `Medium/2026-01-13-3453-Separate-Squares-I`

0 commit comments

Comments
 (0)