Skip to content

Commit de9eb23

Browse files
committed
Improved tags
1 parent e99ac35 commit de9eb23

File tree

9 files changed

+186
-264
lines changed

9 files changed

+186
-264
lines changed

src/main/java/g3401_3500/s3451_find_invalid_ip_addresses/script.sql

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
# Write your MySQL query statement below
2-
# #Hard #2025_02_16_Time_383_ms_(85.47%)_Space_0.0_MB_(100.00%)
2+
# #Hard #Database #2025_02_18_Time_393_ms_(79.56%)_Space_0.0_MB_(100.00%)
33
WITH cte_invalid_ip AS (
44
SELECT log_id, ip
55
FROM logs

src/main/java/g3401_3500/s3452_sum_of_good_numbers/Solution.java

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,13 @@
11
package g3401_3500.s3452_sum_of_good_numbers;
22

3-
// #Easy #2025_02_16_Time_1_ms_(100.00%)_Space_44.30_MB_(100.00%)
3+
// #Easy #Array #2025_02_18_Time_1_ms_(99.99%)_Space_44.75_MB_(7.31%)
44

55
public class Solution {
66
public int sumOfGoodNumbers(int[] nums, int k) {
77
int totalSum = 0;
88
int n = nums.length;
99
for (int i = 0; i < n; i++) {
10-
boolean isGood = true;
11-
if (i - k >= 0 && nums[i] <= nums[i - k]) {
12-
isGood = false;
13-
}
10+
boolean isGood = i - k < 0 || nums[i] > nums[i - k];
1411
if (i + k < n && nums[i] <= nums[i + k]) {
1512
isGood = false;
1613
}
Lines changed: 22 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,42 +1,34 @@
11
package g3401_3500.s3453_separate_squares_i;
22

3-
// #Medium #2025_02_16_Time_123_ms_(100.00%)_Space_87.97_MB_(_%)
3+
// #Medium #Array #Binary_Search #2025_02_18_Time_60_ms_(99.96%)_Space_88.58_MB_(26.92%)
44

55
public class Solution {
6-
private double helper(double line, int[][] squares) {
7-
double aAbove = 0;
8-
double aBelow = 0;
9-
for (int[] square : squares) {
10-
int y = square[1];
11-
int l = square[2];
12-
double total = (double) l * l;
13-
if (line <= y) {
14-
aAbove += total;
15-
} else if (line >= y + l) {
16-
aBelow += total;
6+
public double separateSquares(int[][] squares) {
7+
long hi = 0L;
8+
long lo = 1_000_000_000L;
9+
for (int[] q : squares) {
10+
lo = Math.min(lo, q[1]);
11+
hi = Math.max(hi, q[1] + q[2]);
12+
}
13+
while (lo <= hi) {
14+
long mid = (lo + hi) / 2;
15+
if (diff(mid, squares) <= 0) {
16+
hi = mid - 1;
1717
} else {
18-
// The line intersects the square.
19-
double aboveHeight = (y + l) - line;
20-
double belowHeight = line - y;
21-
aAbove += l * aboveHeight;
22-
aBelow += l * belowHeight;
18+
lo = mid + 1;
2319
}
2420
}
25-
return aAbove - aBelow;
21+
double diff1 = diff(hi, squares);
22+
double diff2 = diff(lo, squares);
23+
return (double) hi + diff1 / (diff1 - diff2);
2624
}
2725

28-
public double separateSquares(int[][] squares) {
29-
double lo = 0;
30-
double hi = 2 * 1e9;
31-
for (int i = 0; i < 60; i++) {
32-
double mid = (lo + hi) / 2.0;
33-
double diff = helper(mid, squares);
34-
if (diff > 0) {
35-
lo = mid;
36-
} else {
37-
hi = mid;
38-
}
26+
private double diff(long mid, int[][] squares) {
27+
double[] res = new double[2];
28+
for (int[] q : squares) {
29+
res[0] += Math.min(q[2], Math.max(0, mid - q[1])) * q[2];
30+
res[1] += Math.min(q[2], Math.max(0, q[1] + q[2] - mid)) * q[2];
3931
}
40-
return hi;
32+
return res[1] - res[0];
4133
}
4234
}
Lines changed: 116 additions & 138 deletions
Original file line numberDiff line numberDiff line change
@@ -1,176 +1,154 @@
11
package g3401_3500.s3454_separate_squares_ii;
22

3-
// #Hard #2025_02_16_Time_246_ms_(100.00%)_Space_79.98_MB_(100.00%)
3+
// #Hard #Array #Binary_Search #Segment_Tree #Line_Sweep
4+
// #2025_02_18_Time_156_ms_(80.18%)_Space_79.96_MB_(64.32%)
45

6+
import java.util.ArrayList;
57
import java.util.Arrays;
6-
import java.util.Comparator;
8+
import java.util.List;
79

810
public class Solution {
9-
public double separateSquares(int[][] squares) {
10-
int n = squares.length;
11-
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) {
22-
Event[] events = new Event[m];
23-
int idx = 0;
24-
for (int[] sq : squares) {
25-
double x = sq[0];
26-
double y = sq[1];
27-
double l = sq[2];
28-
double x2 = x + l;
29-
double y2 = y + l;
30-
events[idx++] = new Event(y, x, x2, 1);
31-
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];
42-
xsRaw[xIdx++] = x;
43-
xsRaw[xIdx++] = x + l;
44-
}
45-
return xsRaw;
46-
}
47-
48-
private double calculateTotalUnionArea(Event[] events, double[] xs, int m) {
49-
SegmentTree segTree = new SegmentTree(xs);
50-
double totalUnionArea = 0.0;
51-
double lastY = events[0].y;
52-
int i = 0;
53-
while (i < m) {
54-
double curY = events[i].y;
55-
if (curY > lastY) {
56-
double unionX = segTree.query();
57-
totalUnionArea += unionX * (curY - lastY);
58-
lastY = curY;
59-
}
60-
while (i < m && events[i].y == curY) {
61-
int[] indices = findIndices(xs, events[i]);
62-
segTree.update(1, 0, xs.length - 1, indices[0], indices[1], events[i].type);
63-
i++;
64-
}
65-
}
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;
72-
double cumArea = 0.0;
73-
int i = 0;
74-
while (i < m) {
75-
double curY = events[i].y;
76-
if (curY > lastY) {
77-
double unionX = segTree.query();
78-
double dy = curY - lastY;
79-
if (cumArea + unionX * dy >= target - 1e-10) {
80-
return lastY + (target - cumArea) / unionX;
81-
}
82-
cumArea += unionX * dy;
83-
lastY = curY;
84-
}
85-
while (i < m && events[i].y == curY) {
86-
int[] indices = findIndices(xs, events[i]);
87-
segTree.update(1, 0, xs.length - 1, indices[0], indices[1], events[i].type);
88-
i++;
89-
}
90-
}
91-
return lastY;
92-
}
93-
94-
private int[] findIndices(double[] xs, Event event) {
95-
int lIdx = Arrays.binarySearch(xs, event.x1);
96-
if (lIdx < 0) {
97-
lIdx = -lIdx - 1;
98-
}
99-
int rIdx = Arrays.binarySearch(xs, event.x2);
100-
if (rIdx < 0) {
101-
rIdx = -rIdx - 1;
102-
}
103-
return new int[] {lIdx, rIdx};
104-
}
105-
106-
private double[] compress(double[] arr) {
107-
Arrays.sort(arr);
108-
int cnt = 1;
109-
for (int i = 1; i < arr.length; i++) {
110-
if (arr[i] != arr[i - 1]) {
111-
cnt++;
112-
}
113-
}
114-
double[] res = new double[cnt];
115-
res[0] = arr[0];
116-
int j = 1;
117-
for (int i = 1; i < arr.length; i++) {
118-
if (arr[i] != arr[i - 1]) {
119-
res[j++] = arr[i];
120-
}
121-
}
122-
return res;
123-
}
124-
125-
private static class Event {
11+
private static class Event implements Comparable<Event> {
12612
double y;
127-
double x1;
128-
double x2;
13+
int x1;
14+
int x2;
12915
int type;
13016

131-
Event(double y, double x1, double x2, int type) {
17+
Event(double y, int x1, int x2, int type) {
13218
this.y = y;
13319
this.x1 = x1;
13420
this.x2 = x2;
13521
this.type = type;
13622
}
23+
24+
public int compareTo(Event other) {
25+
return Double.compare(this.y, other.y);
26+
}
27+
}
28+
29+
private static class Segment {
30+
double y1;
31+
double y2;
32+
double unionX;
33+
double cumArea;
34+
35+
Segment(double y1, double y2, double unionX, double cumArea) {
36+
this.y1 = y1;
37+
this.y2 = y2;
38+
this.unionX = unionX;
39+
this.cumArea = cumArea;
40+
}
13741
}
13842

13943
private static class SegmentTree {
140-
int n;
141-
double[] tree;
14244
int[] count;
143-
double[] xs;
45+
double[] len;
46+
int n;
47+
int[] x;
14448

145-
SegmentTree(double[] xs) {
146-
this.xs = xs;
147-
this.n = xs.length;
148-
tree = new double[4 * n];
49+
SegmentTree(int[] x) {
50+
this.x = x;
51+
n = x.length - 1;
14952
count = new int[4 * n];
53+
len = new double[4 * n];
15054
}
15155

15256
void update(int idx, int l, int r, int ql, int qr, int val) {
153-
if (qr <= l || ql >= r) {
57+
if (qr < l || ql > r) {
15458
return;
15559
}
15660
if (ql <= l && r <= qr) {
15761
count[idx] += val;
15862
} else {
159-
int mid = (l + r) >> 1;
160-
update(idx << 1, l, mid, ql, qr, val);
161-
update(idx << 1 | 1, mid, r, ql, qr, val);
63+
int mid = (l + r) / 2;
64+
update(2 * idx + 1, l, mid, ql, qr, val);
65+
update(2 * idx + 2, mid + 1, r, ql, qr, val);
16266
}
16367
if (count[idx] > 0) {
164-
tree[idx] = xs[r] - xs[l];
165-
} else if (r - l == 1) {
166-
tree[idx] = 0;
68+
len[idx] = x[r + 1] - x[l];
16769
} else {
168-
tree[idx] = tree[idx << 1] + tree[idx << 1 | 1];
70+
if (l == r) {
71+
len[idx] = 0;
72+
} else {
73+
len[idx] = len[2 * idx + 1] + len[2 * idx + 2];
74+
}
16975
}
17076
}
17177

78+
void update(int ql, int qr, int val) {
79+
update(0, 0, n - 1, ql, qr, val);
80+
}
81+
17282
double query() {
173-
return tree[1];
83+
return len[0];
84+
}
85+
}
86+
87+
public double separateSquares(int[][] squares) {
88+
int n = squares.length;
89+
Event[] events = new Event[2 * n];
90+
int idx = 0;
91+
List<Integer> xList = new ArrayList<>();
92+
for (int[] s : squares) {
93+
int x = s[0];
94+
int y = s[1];
95+
int l = s[2];
96+
int x2 = x + l;
97+
int y2 = y + l;
98+
events[idx++] = new Event(y, x, x2, 1);
99+
events[idx++] = new Event(y2, x, x2, -1);
100+
xList.add(x);
101+
xList.add(x2);
102+
}
103+
Arrays.sort(events);
104+
int m = xList.size();
105+
int[] xCords = new int[m];
106+
for (int i = 0; i < m; i++) {
107+
xCords[i] = xList.get(i);
108+
}
109+
Arrays.sort(xCords);
110+
int uniqueCount = 0;
111+
for (int i = 0; i < m; i++) {
112+
if (i == 0 || xCords[i] != xCords[i - 1]) {
113+
xCords[uniqueCount++] = xCords[i];
114+
}
115+
}
116+
int[] x = Arrays.copyOf(xCords, uniqueCount);
117+
SegmentTree segTree = new SegmentTree(x);
118+
List<Segment> segments = new ArrayList<>();
119+
double cumArea = 0.0;
120+
double lastY = events[0].y;
121+
int iEvent = 0;
122+
while (iEvent < events.length) {
123+
double currentY = events[iEvent].y;
124+
double delta = currentY - lastY;
125+
if (delta > 0) {
126+
double unionX = segTree.query();
127+
segments.add(new Segment(lastY, currentY, unionX, cumArea));
128+
cumArea += unionX * delta;
129+
}
130+
while (iEvent < events.length && events[iEvent].y == currentY) {
131+
Event e = events[iEvent];
132+
int left = Arrays.binarySearch(x, e.x1);
133+
int right = Arrays.binarySearch(x, e.x2);
134+
if (left < right) {
135+
segTree.update(left, right - 1, e.type);
136+
}
137+
iEvent++;
138+
}
139+
lastY = currentY;
140+
}
141+
double totalArea = cumArea;
142+
double target = totalArea / 2.0;
143+
double answer;
144+
for (Segment seg : segments) {
145+
double segArea = seg.unionX * (seg.y2 - seg.y1);
146+
if (seg.cumArea + segArea >= target) {
147+
double needed = target - seg.cumArea;
148+
answer = seg.y1 + needed / seg.unionX;
149+
return answer;
150+
}
174151
}
152+
return lastY;
175153
}
176154
}

src/main/java/g3401_3500/s3455_shortest_matching_substring/Solution.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package g3401_3500.s3455_shortest_matching_substring;
22

3-
// #Hard #2025_02_16_Time_91_ms_(100.00%)_Space_55.37_MB_(100.00%)
3+
// #Hard #String #Binary_Search #Two_Pointers #String_Matching
4+
// #2025_02_18_Time_116_ms_(81.44%)_Space_55.28_MB_(88.02%)
45

56
import java.util.ArrayList;
67
import java.util.Arrays;

0 commit comments

Comments
 (0)