Skip to content

Commit 414febb

Browse files
committed
Fixed sonar
1 parent 0890b14 commit 414febb

File tree

1 file changed

+50
-47
lines changed

1 file changed

+50
-47
lines changed

src/main/java/g3401_3500/s3454_separate_squares_ii/Solution.java

+50-47
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
package g3401_3500.s3454_separate_squares_ii;
22

3-
// #Hard #2025_02_16_Time_243_ms_(100.00%)_Space_76.06_MB_(100.00%)
3+
// #Hard #2025_02_16_Time_246_ms_(100.00%)_Space_79.98_MB_(100.00%)
44

55
import java.util.Arrays;
66
import java.util.Comparator;
@@ -9,86 +9,99 @@ public class Solution {
99
public double separateSquares(int[][] squares) {
1010
int n = squares.length;
1111
int m = 2 * n;
12+
Event[] events = createEvents(squares, m);
13+
double[] xsRaw = createXsRaw(squares, m);
14+
Arrays.sort(events, Comparator.comparingDouble(e -> e.y));
15+
double[] xs = compress(xsRaw);
16+
double totalUnionArea = calculateTotalUnionArea(events, xs, m);
17+
double target = totalUnionArea / 2.0;
18+
return findSplitPoint(events, xs, m, target);
19+
}
20+
21+
private Event[] createEvents(int[][] squares, int m) {
1222
Event[] events = new Event[m];
13-
double[] xsRaw = new double[m];
1423
int idx = 0;
15-
int xIdx = 0;
1624
for (int[] sq : squares) {
17-
// Each square gives a rectangle [x, x+l] x [y, y+l]
1825
double x = sq[0];
1926
double y = sq[1];
2027
double l = sq[2];
2128
double x2 = x + l;
2229
double y2 = y + l;
2330
events[idx++] = new Event(y, x, x2, 1);
2431
events[idx++] = new Event(y2, x, x2, -1);
32+
}
33+
return events;
34+
}
35+
36+
private double[] createXsRaw(int[][] squares, int m) {
37+
double[] xsRaw = new double[m];
38+
int xIdx = 0;
39+
for (int[] sq : squares) {
40+
double x = sq[0];
41+
double l = sq[2];
2542
xsRaw[xIdx++] = x;
26-
xsRaw[xIdx++] = x2;
43+
xsRaw[xIdx++] = x + l;
2744
}
28-
// Sort events by their y-coordinate (they are exact integers in double format)
29-
Arrays.sort(events, Comparator.comparingDouble(e -> e.y));
30-
// Compress x-coordinates
31-
double[] xs = compress(xsRaw);
32-
// FIRST SWEEP: compute total union area.
45+
return xsRaw;
46+
}
47+
48+
private double calculateTotalUnionArea(Event[] events, double[] xs, int m) {
3349
SegmentTree segTree = new SegmentTree(xs);
3450
double totalUnionArea = 0.0;
3551
double lastY = events[0].y;
36-
for (int i = 0; i < m; ) {
52+
int i = 0;
53+
while (i < m) {
3754
double curY = events[i].y;
3855
if (curY > lastY) {
3956
double unionX = segTree.query();
4057
totalUnionArea += unionX * (curY - lastY);
4158
lastY = curY;
4259
}
43-
// Process all events at y == curY
4460
while (i < m && events[i].y == curY) {
45-
int lIdx = Arrays.binarySearch(xs, events[i].x1);
46-
if (lIdx < 0) {
47-
lIdx = -lIdx - 1;
48-
}
49-
int rIdx = Arrays.binarySearch(xs, events[i].x2);
50-
if (rIdx < 0) {
51-
rIdx = -rIdx - 1;
52-
}
53-
segTree.update(1, 0, xs.length - 1, lIdx, rIdx, events[i].type);
61+
int[] indices = findIndices(xs, events[i]);
62+
segTree.update(1, 0, xs.length - 1, indices[0], indices[1], events[i].type);
5463
i++;
5564
}
5665
}
57-
double target = totalUnionArea / 2.0;
58-
// SECOND SWEEP: find minimal y such that cumulative union area reaches target.
59-
// Reinitialize segment tree for a fresh sweep.
60-
segTree = new SegmentTree(xs);
61-
lastY = events[0].y;
66+
return totalUnionArea;
67+
}
68+
69+
private double findSplitPoint(Event[] events, double[] xs, int m, double target) {
70+
SegmentTree segTree = new SegmentTree(xs);
71+
double lastY = events[0].y;
6272
double cumArea = 0.0;
6373
for (int i = 0; i < m; ) {
6474
double curY = events[i].y;
6575
if (curY > lastY) {
6676
double unionX = segTree.query();
6777
double dy = curY - lastY;
6878
if (cumArea + unionX * dy >= target - 1e-10) {
69-
// The answer lies in this interval.
7079
return lastY + (target - cumArea) / unionX;
7180
}
7281
cumArea += unionX * dy;
7382
lastY = curY;
7483
}
7584
while (i < m && events[i].y == curY) {
76-
int lIdx = Arrays.binarySearch(xs, events[i].x1);
77-
if (lIdx < 0) {
78-
lIdx = -lIdx - 1;
79-
}
80-
int rIdx = Arrays.binarySearch(xs, events[i].x2);
81-
if (rIdx < 0) {
82-
rIdx = -rIdx - 1;
83-
}
84-
segTree.update(1, 0, xs.length - 1, lIdx, rIdx, events[i].type);
85+
int[] indices = findIndices(xs, events[i]);
86+
segTree.update(1, 0, xs.length - 1, indices[0], indices[1], events[i].type);
8587
i++;
8688
}
8789
}
8890
return lastY;
8991
}
9092

91-
// Compress an array of doubles into a sorted array of unique values.
93+
private int[] findIndices(double[] xs, Event event) {
94+
int lIdx = Arrays.binarySearch(xs, event.x1);
95+
if (lIdx < 0) {
96+
lIdx = -lIdx - 1;
97+
}
98+
int rIdx = Arrays.binarySearch(xs, event.x2);
99+
if (rIdx < 0) {
100+
rIdx = -rIdx - 1;
101+
}
102+
return new int[] {lIdx, rIdx};
103+
}
104+
92105
private double[] compress(double[] arr) {
93106
Arrays.sort(arr);
94107
int cnt = 1;
@@ -108,12 +121,10 @@ private double[] compress(double[] arr) {
108121
return res;
109122
}
110123

111-
// Event class for the sweep-line.
112124
private static class Event {
113125
double y;
114126
double x1;
115127
double x2;
116-
// +1 for adding an interval; -1 for removing.
117128
int type;
118129

119130
Event(double y, double x1, double x2, int type) {
@@ -124,26 +135,19 @@ private static class Event {
124135
}
125136
}
126137

127-
// Segment Tree for maintaining the union length over the x-axis.
128138
private static class SegmentTree {
129139
int n;
130-
// Covered length of the segment.
131140
double[] tree;
132-
// Coverage count for the segment.
133141
int[] count;
134-
// The compressed x-coordinates.
135142
double[] xs;
136143

137144
SegmentTree(double[] xs) {
138145
this.xs = xs;
139146
this.n = xs.length;
140-
// Allocate 4*n size arrays.
141147
tree = new double[4 * n];
142148
count = new int[4 * n];
143149
}
144150

145-
// Update the range [ql, qr) with value 'val'.
146-
// The current node covers indices [l, r) in xs.
147151
void update(int idx, int l, int r, int ql, int qr, int val) {
148152
if (qr <= l || ql >= r) {
149153
return;
@@ -164,7 +168,6 @@ void update(int idx, int l, int r, int ql, int qr, int val) {
164168
}
165169
}
166170

167-
// Query the current total union length.
168171
double query() {
169172
return tree[1];
170173
}

0 commit comments

Comments
 (0)