Skip to content

Commit 01a8a00

Browse files
committed
Added tasks 3451-3459
1 parent 8bfb872 commit 01a8a00

File tree

27 files changed

+1288
-0
lines changed

27 files changed

+1288
-0
lines changed
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
3451\. Find Invalid IP Addresses
2+
3+
Hard
4+
5+
Table: `logs`
6+
7+
+-------------+---------+
8+
| Column Name | Type |
9+
+-------------+---------+
10+
| log_id | int |
11+
| ip | varchar |
12+
| status_code | int |
13+
+-------------+---------+
14+
log_id is the unique key for this table.
15+
Each row contains server access log information including IP address and HTTP status code.
16+
17+
Write a solution to find **invalid IP addresses**. An IPv4 address is invalid if it meets any of these conditions:
18+
19+
* Contains numbers **greater than** `255` in any octet
20+
* Has **leading zeros** in any octet (like `01.02.03.04`)
21+
* Has **less or more** than `4` octets
22+
23+
Return _the result table_ _ordered by_ `invalid_count`, `ip` _in **descending** order respectively_.
24+
25+
The result format is in the following example.
26+
27+
**Example:**
28+
29+
**Input:**
30+
31+
logs table:
32+
33+
+--------+---------------+-------------+
34+
| log_id | ip | status_code |
35+
+--------+---------------+-------------+
36+
| 1 | 192.168.1.1 | 200 |
37+
| 2 | 256.1.2.3 | 404 |
38+
| 3 | 192.168.001.1 | 200 |
39+
| 4 | 192.168.1.1 | 200 |
40+
| 5 | 192.168.1 | 500 |
41+
| 6 | 256.1.2.3 | 404 |
42+
| 7 | 192.168.001.1 | 200 |
43+
+--------+---------------+-------------+
44+
45+
**Output:**
46+
47+
+---------------+--------------+
48+
| ip | invalid_count|
49+
+---------------+--------------+
50+
| 256.1.2.3 | 2 |
51+
| 192.168.001.1 | 2 |
52+
| 192.168.1 | 1 |
53+
+---------------+--------------+
54+
55+
**Explanation:**
56+
57+
* 256.1.2.3 is invalid because 256 > 255
58+
* 192.168.001.1 is invalid because of leading zeros
59+
* 192.168.1 is invalid because it has only 3 octets
60+
61+
The output table is ordered by invalid\_count, ip in descending order respectively.
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
# Write your MySQL query statement below
2+
# #Hard #2025_02_16_Time_383_ms_(85.47%)_Space_0.0_MB_(100.00%)
3+
WITH cte_invalid_ip AS (
4+
SELECT log_id, ip
5+
FROM logs
6+
WHERE NOT regexp_like(ip, '^(?:[1-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])(?:[.](?:[1-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])){3}$')
7+
),
8+
cte_invalid_ip_count AS (
9+
SELECT ip, count(log_id) as invalid_count
10+
FROM cte_invalid_ip
11+
GROUP BY ip
12+
)
13+
SELECT ip, invalid_count
14+
FROM cte_invalid_ip_count
15+
ORDER BY invalid_count DESC, ip DESC;
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
package g3401_3500.s3452_sum_of_good_numbers
2+
3+
// #Easy #Array #2025_02_18_Time_1_ms_(100.00%)_Space_38.08_MB_(84.85%)
4+
5+
class Solution {
6+
fun sumOfGoodNumbers(nums: IntArray, k: Int): Int {
7+
var totalSum = 0
8+
val n = nums.size
9+
for (i in 0..<n) {
10+
var isGood = true
11+
if (i - k >= 0 && nums[i] <= nums[i - k]) {
12+
isGood = false
13+
}
14+
if (i + k < n && nums[i] <= nums[i + k]) {
15+
isGood = false
16+
}
17+
if (isGood) {
18+
totalSum += nums[i]
19+
}
20+
}
21+
return totalSum
22+
}
23+
}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
3452\. Sum of Good Numbers
2+
3+
Easy
4+
5+
Given an array of integers `nums` and an integer `k`, an element `nums[i]` is considered **good** if it is **strictly** greater than the elements at indices `i - k` and `i + k` (if those indices exist). If neither of these indices _exists_, `nums[i]` is still considered **good**.
6+
7+
Return the **sum** of all the **good** elements in the array.
8+
9+
**Example 1:**
10+
11+
**Input:** nums = [1,3,2,1,5,4], k = 2
12+
13+
**Output:** 12
14+
15+
**Explanation:**
16+
17+
The good numbers are `nums[1] = 3`, `nums[4] = 5`, and `nums[5] = 4` because they are strictly greater than the numbers at indices `i - k` and `i + k`.
18+
19+
**Example 2:**
20+
21+
**Input:** nums = [2,1], k = 1
22+
23+
**Output:** 2
24+
25+
**Explanation:**
26+
27+
The only good number is `nums[0] = 2` because it is strictly greater than `nums[1]`.
28+
29+
**Constraints:**
30+
31+
* `2 <= nums.length <= 100`
32+
* `1 <= nums[i] <= 1000`
33+
* `1 <= k <= floor(nums.length / 2)`
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
package g3401_3500.s3453_separate_squares_i
2+
3+
// #Medium #Array #Binary_Search #2025_02_18_Time_134_ms_(30.30%)_Space_95.92_MB_(93.94%)
4+
5+
class Solution {
6+
private fun helper(line: Double, squares: Array<IntArray>): Double {
7+
var aAbove = 0.0
8+
var aBelow = 0.0
9+
for (square in squares) {
10+
val y = square[1]
11+
val l = square[2]
12+
val total = l.toDouble() * l
13+
if (line <= y) {
14+
aAbove += total
15+
} else if (line >= y + l) {
16+
aBelow += total
17+
} else {
18+
// The line intersects the square.
19+
val aboveHeight = (y + l) - line
20+
val belowHeight = line - y
21+
aAbove += l * aboveHeight
22+
aBelow += l * belowHeight
23+
}
24+
}
25+
return aAbove - aBelow
26+
}
27+
28+
fun separateSquares(squares: Array<IntArray>): Double {
29+
var lo = 0.0
30+
var hi = 2 * 1e9
31+
for (i in 0..59) {
32+
val mid = (lo + hi) / 2.0
33+
val diff = helper(mid, squares)
34+
if (diff > 0) {
35+
lo = mid
36+
} else {
37+
hi = mid
38+
}
39+
}
40+
return hi
41+
}
42+
}
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
3453\. Separate Squares I
2+
3+
Medium
4+
5+
You are given a 2D integer array `squares`. Each <code>squares[i] = [x<sub>i</sub>, y<sub>i</sub>, l<sub>i</sub>]</code> represents the coordinates of the bottom-left point and the side length of a square parallel to the x-axis.
6+
7+
Find the **minimum** y-coordinate value of a horizontal line such that the total area of the squares above the line _equals_ the total area of the squares below the line.
8+
9+
Answers within <code>10<sup>-5</sup></code> of the actual answer will be accepted.
10+
11+
**Note**: Squares **may** overlap. Overlapping areas should be counted **multiple times**.
12+
13+
**Example 1:**
14+
15+
**Input:** squares = [[0,0,1],[2,2,1]]
16+
17+
**Output:** 1.00000
18+
19+
**Explanation:**
20+
21+
![](https://assets.leetcode.com/uploads/2025/01/06/4062example1drawio.png)
22+
23+
Any horizontal line between `y = 1` and `y = 2` will have 1 square unit above it and 1 square unit below it. The lowest option is 1.
24+
25+
**Example 2:**
26+
27+
**Input:** squares = [[0,0,2],[1,1,1]]
28+
29+
**Output:** 1.16667
30+
31+
**Explanation:**
32+
33+
![](https://assets.leetcode.com/uploads/2025/01/15/4062example2drawio.png)
34+
35+
The areas are:
36+
37+
* Below the line: `7/6 * 2 (Red) + 1/6 (Blue) = 15/6 = 2.5`.
38+
* Above the line: `5/6 * 2 (Red) + 5/6 (Blue) = 15/6 = 2.5`.
39+
40+
Since the areas above and below the line are equal, the output is `7/6 = 1.16667`.
41+
42+
**Constraints:**
43+
44+
* <code>1 <= squares.length <= 5 * 10<sup>4</sup></code>
45+
* <code>squares[i] = [x<sub>i</sub>, y<sub>i</sub>, l<sub>i</sub>]</code>
46+
* `squares[i].length == 3`
47+
* <code>0 <= x<sub>i</sub>, y<sub>i</sub> <= 10<sup>9</sup></code>
48+
* <code>1 <= l<sub>i</sub> <= 10<sup>9</sup></code>
Lines changed: 160 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,160 @@
1+
package g3401_3500.s3454_separate_squares_ii
2+
3+
// #Hard #Array #Binary_Search #Segment_Tree #Line_Sweep
4+
// #2025_02_18_Time_277_ms_(100.00%)_Space_96.52_MB_(33.33%)
5+
6+
class Solution {
7+
fun separateSquares(squares: Array<IntArray>): Double {
8+
val n = squares.size
9+
val m = 2 * n
10+
val events = createEvents(squares, m)
11+
val xsRaw = createXsRaw(squares, m)
12+
events.sortWith<Event?> { a, b: Event? -> a!!.y.compareTo(b!!.y) }
13+
val xs = compress(xsRaw)
14+
val totalUnionArea = calculateTotalUnionArea(events, xs, m)
15+
val target = totalUnionArea / 2.0
16+
return findSplitPoint(events, xs, m, target)
17+
}
18+
19+
private fun createEvents(squares: Array<IntArray>, m: Int): Array<Event?> {
20+
val events = arrayOfNulls<Event>(m)
21+
var idx = 0
22+
for (sq in squares) {
23+
val x = sq[0].toDouble()
24+
val y = sq[1].toDouble()
25+
val l = sq[2].toDouble()
26+
val x2 = x + l
27+
val y2 = y + l
28+
events[idx++] = Event(y, x, x2, 1)
29+
events[idx++] = Event(y2, x, x2, -1)
30+
}
31+
return events
32+
}
33+
34+
private fun createXsRaw(squares: Array<IntArray>, m: Int): DoubleArray {
35+
val xsRaw = DoubleArray(m)
36+
var xIdx = 0
37+
for (sq in squares) {
38+
val x = sq[0].toDouble()
39+
val l = sq[2].toDouble()
40+
xsRaw[xIdx++] = x
41+
xsRaw[xIdx++] = x + l
42+
}
43+
return xsRaw
44+
}
45+
46+
private fun calculateTotalUnionArea(events: Array<Event?>, xs: DoubleArray, m: Int): Double {
47+
val segTree = SegmentTree(xs)
48+
var totalUnionArea = 0.0
49+
var lastY = events[0]!!.y
50+
var i = 0
51+
while (i < m) {
52+
val curY = events[i]!!.y
53+
if (curY > lastY) {
54+
val unionX = segTree.query()
55+
totalUnionArea += unionX * (curY - lastY)
56+
lastY = curY
57+
}
58+
while (i < m && events[i]!!.y == curY) {
59+
val indices = findIndices(xs, events[i]!!)
60+
segTree.update(1, 0, xs.size - 1, indices[0], indices[1], events[i]!!.type)
61+
i++
62+
}
63+
}
64+
return totalUnionArea
65+
}
66+
67+
private fun findSplitPoint(events: Array<Event?>, xs: DoubleArray, m: Int, target: Double): Double {
68+
val segTree = SegmentTree(xs)
69+
var lastY = events[0]!!.y
70+
var cumArea = 0.0
71+
var i = 0
72+
while (i < m) {
73+
val curY = events[i]!!.y
74+
if (curY > lastY) {
75+
val unionX = segTree.query()
76+
val dy = curY - lastY
77+
if (cumArea + unionX * dy >= target - 1e-10) {
78+
return lastY + (target - cumArea) / unionX
79+
}
80+
cumArea += unionX * dy
81+
lastY = curY
82+
}
83+
while (i < m && events[i]!!.y == curY) {
84+
val indices = findIndices(xs, events[i]!!)
85+
segTree.update(1, 0, xs.size - 1, indices[0], indices[1], events[i]!!.type)
86+
i++
87+
}
88+
}
89+
return lastY
90+
}
91+
92+
private fun findIndices(xs: DoubleArray, event: Event): IntArray {
93+
var lIdx = xs.binarySearch(event.x1)
94+
if (lIdx < 0) {
95+
lIdx = -lIdx - 1
96+
}
97+
var rIdx = xs.binarySearch(event.x2)
98+
if (rIdx < 0) {
99+
rIdx = -rIdx - 1
100+
}
101+
return intArrayOf(lIdx, rIdx)
102+
}
103+
104+
private fun compress(arr: DoubleArray): DoubleArray {
105+
arr.sort()
106+
var cnt = 1
107+
for (i in 1..<arr.size) {
108+
if (arr[i] != arr[i - 1]) {
109+
cnt++
110+
}
111+
}
112+
val res = DoubleArray(cnt)
113+
res[0] = arr[0]
114+
var j = 1
115+
for (i in 1..<arr.size) {
116+
if (arr[i] != arr[i - 1]) {
117+
res[j++] = arr[i]
118+
}
119+
}
120+
return res
121+
}
122+
123+
private class Event(var y: Double, var x1: Double, var x2: Double, var type: Int)
124+
125+
private class SegmentTree(var xs: DoubleArray) {
126+
var n: Int
127+
var tree: DoubleArray
128+
var count: IntArray
129+
130+
init {
131+
this.n = xs.size
132+
tree = DoubleArray(4 * n)
133+
count = IntArray(4 * n)
134+
}
135+
136+
fun update(idx: Int, l: Int, r: Int, ql: Int, qr: Int, `val`: Int) {
137+
if (qr <= l || ql >= r) {
138+
return
139+
}
140+
if (ql <= l && r <= qr) {
141+
count[idx] += `val`
142+
} else {
143+
val mid = (l + r) shr 1
144+
update(idx shl 1, l, mid, ql, qr, `val`)
145+
update(idx shl 1 or 1, mid, r, ql, qr, `val`)
146+
}
147+
if (count[idx] > 0) {
148+
tree[idx] = xs[r] - xs[l]
149+
} else if (r - l == 1) {
150+
tree[idx] = 0.0
151+
} else {
152+
tree[idx] = tree[idx shl 1] + tree[idx shl 1 or 1]
153+
}
154+
}
155+
156+
fun query(): Double {
157+
return tree[1]
158+
}
159+
}
160+
}

0 commit comments

Comments
 (0)