diff --git a/src/main/kotlin/g3401_3500/s3451_find_invalid_ip_addresses/readme.md b/src/main/kotlin/g3401_3500/s3451_find_invalid_ip_addresses/readme.md new file mode 100644 index 000000000..458a6a95e --- /dev/null +++ b/src/main/kotlin/g3401_3500/s3451_find_invalid_ip_addresses/readme.md @@ -0,0 +1,61 @@ +3451\. Find Invalid IP Addresses + +Hard + +Table: `logs` + + +-------------+---------+ + | Column Name | Type | + +-------------+---------+ + | log_id | int | + | ip | varchar | + | status_code | int | + +-------------+---------+ + log_id is the unique key for this table. + Each row contains server access log information including IP address and HTTP status code. + +Write a solution to find **invalid IP addresses**. An IPv4 address is invalid if it meets any of these conditions: + +* Contains numbers **greater than** `255` in any octet +* Has **leading zeros** in any octet (like `01.02.03.04`) +* Has **less or more** than `4` octets + +Return _the result table_ _ordered by_ `invalid_count`, `ip` _in **descending** order respectively_. + +The result format is in the following example. + +**Example:** + +**Input:** + +logs table: + + +--------+---------------+-------------+ + | log_id | ip | status_code | + +--------+---------------+-------------+ + | 1 | 192.168.1.1 | 200 | + | 2 | 256.1.2.3 | 404 | + | 3 | 192.168.001.1 | 200 | + | 4 | 192.168.1.1 | 200 | + | 5 | 192.168.1 | 500 | + | 6 | 256.1.2.3 | 404 | + | 7 | 192.168.001.1 | 200 | + +--------+---------------+-------------+ + +**Output:** + + +---------------+--------------+ + | ip | invalid_count| + +---------------+--------------+ + | 256.1.2.3 | 2 | + | 192.168.001.1 | 2 | + | 192.168.1 | 1 | + +---------------+--------------+ + +**Explanation:** + +* 256.1.2.3 is invalid because 256 > 255 +* 192.168.001.1 is invalid because of leading zeros +* 192.168.1 is invalid because it has only 3 octets + +The output table is ordered by invalid\_count, ip in descending order respectively. \ No newline at end of file diff --git a/src/main/kotlin/g3401_3500/s3451_find_invalid_ip_addresses/script.sql b/src/main/kotlin/g3401_3500/s3451_find_invalid_ip_addresses/script.sql new file mode 100644 index 000000000..6df819211 --- /dev/null +++ b/src/main/kotlin/g3401_3500/s3451_find_invalid_ip_addresses/script.sql @@ -0,0 +1,15 @@ +# Write your MySQL query statement below +# #Hard #Database #2025_02_18_Time_309_ms_(90.61%)_Space_0.0_MB_(100.00%) +WITH cte_invalid_ip AS ( + SELECT log_id, ip + FROM logs + 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}$') + ), + cte_invalid_ip_count AS ( + SELECT ip, count(log_id) as invalid_count + FROM cte_invalid_ip + GROUP BY ip + ) +SELECT ip, invalid_count +FROM cte_invalid_ip_count +ORDER BY invalid_count DESC, ip DESC; diff --git a/src/main/kotlin/g3401_3500/s3452_sum_of_good_numbers/Solution.kt b/src/main/kotlin/g3401_3500/s3452_sum_of_good_numbers/Solution.kt new file mode 100644 index 000000000..032cddf7d --- /dev/null +++ b/src/main/kotlin/g3401_3500/s3452_sum_of_good_numbers/Solution.kt @@ -0,0 +1,23 @@ +package g3401_3500.s3452_sum_of_good_numbers + +// #Easy #Array #2025_02_18_Time_1_ms_(100.00%)_Space_38.08_MB_(84.85%) + +class Solution { + fun sumOfGoodNumbers(nums: IntArray, k: Int): Int { + var totalSum = 0 + val n = nums.size + for (i in 0..= 0 && nums[i] <= nums[i - k]) { + isGood = false + } + if (i + k < n && nums[i] <= nums[i + k]) { + isGood = false + } + if (isGood) { + totalSum += nums[i] + } + } + return totalSum + } +} diff --git a/src/main/kotlin/g3401_3500/s3452_sum_of_good_numbers/readme.md b/src/main/kotlin/g3401_3500/s3452_sum_of_good_numbers/readme.md new file mode 100644 index 000000000..f6a899293 --- /dev/null +++ b/src/main/kotlin/g3401_3500/s3452_sum_of_good_numbers/readme.md @@ -0,0 +1,33 @@ +3452\. Sum of Good Numbers + +Easy + +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**. + +Return the **sum** of all the **good** elements in the array. + +**Example 1:** + +**Input:** nums = [1,3,2,1,5,4], k = 2 + +**Output:** 12 + +**Explanation:** + +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`. + +**Example 2:** + +**Input:** nums = [2,1], k = 1 + +**Output:** 2 + +**Explanation:** + +The only good number is `nums[0] = 2` because it is strictly greater than `nums[1]`. + +**Constraints:** + +* `2 <= nums.length <= 100` +* `1 <= nums[i] <= 1000` +* `1 <= k <= floor(nums.length / 2)` \ No newline at end of file diff --git a/src/main/kotlin/g3401_3500/s3453_separate_squares_i/Solution.kt b/src/main/kotlin/g3401_3500/s3453_separate_squares_i/Solution.kt new file mode 100644 index 000000000..12b62e759 --- /dev/null +++ b/src/main/kotlin/g3401_3500/s3453_separate_squares_i/Solution.kt @@ -0,0 +1,58 @@ +package g3401_3500.s3453_separate_squares_i + +// #Medium #Array #Binary_Search #2025_02_18_Time_57_ms_(100.00%)_Space_102.84_MB_(84.85%) + +class Solution { + fun separateSquares(squares: Array): Double { + val n = squares.size + val arr = Array(n) { LongArray(3) } + var total = 0.0 + var left = Long.MAX_VALUE + var right = Long.MIN_VALUE + for (i in 0..n - 1) { + val y = squares[i][1].toLong() + val z = squares[i][2].toLong() + arr[i][0] = y + arr[i][1] = y + z + arr[i][2] = z + total += (z * z).toDouble() + left = minOf(left, arr[i][0]) + right = maxOf(right, arr[i][1]) + } + while (left < right) { + val mid = (left + right) / 2 + var low = 0.0 + for (a in arr) { + if (a[0] >= mid) { + continue + } else if (a[1] <= mid) { + low += a[2] * a[2] + } else { + low += a[2] * (mid - a[0]) + } + } + if (low + low + 0.00001 >= total) { + right = mid + } else { + left = mid + 1 + } + } + left = right - 1 + var a1 = 0.0 + var a2 = 0.0 + for (a in arr) { + val x = a[0] + val y = a[1] + val z = a[2] + if (left > x) { + a1 += (minOf(y, left) - x) * z.toDouble() + } + if (right < y) { + a2 += (y - maxOf(x, right)) * z.toDouble() + } + } + val goal = (total - a1 - a1) / 2 + val len = total - a1 - a2 + return right - 1 + (goal / len) + } +} diff --git a/src/main/kotlin/g3401_3500/s3453_separate_squares_i/readme.md b/src/main/kotlin/g3401_3500/s3453_separate_squares_i/readme.md new file mode 100644 index 000000000..19f128d6e --- /dev/null +++ b/src/main/kotlin/g3401_3500/s3453_separate_squares_i/readme.md @@ -0,0 +1,48 @@ +3453\. Separate Squares I + +Medium + +You are given a 2D integer array `squares`. Each squares[i] = [xi, yi, li] represents the coordinates of the bottom-left point and the side length of a square parallel to the x-axis. + +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. + +Answers within 10-5 of the actual answer will be accepted. + +**Note**: Squares **may** overlap. Overlapping areas should be counted **multiple times**. + +**Example 1:** + +**Input:** squares = [[0,0,1],[2,2,1]] + +**Output:** 1.00000 + +**Explanation:** + +![](https://assets.leetcode.com/uploads/2025/01/06/4062example1drawio.png) + +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. + +**Example 2:** + +**Input:** squares = [[0,0,2],[1,1,1]] + +**Output:** 1.16667 + +**Explanation:** + +![](https://assets.leetcode.com/uploads/2025/01/15/4062example2drawio.png) + +The areas are: + +* Below the line: `7/6 * 2 (Red) + 1/6 (Blue) = 15/6 = 2.5`. +* Above the line: `5/6 * 2 (Red) + 5/6 (Blue) = 15/6 = 2.5`. + +Since the areas above and below the line are equal, the output is `7/6 = 1.16667`. + +**Constraints:** + +* 1 <= squares.length <= 5 * 104 +* squares[i] = [xi, yi, li] +* `squares[i].length == 3` +* 0 <= xi, yi <= 109 +* 1 <= li <= 109 \ No newline at end of file diff --git a/src/main/kotlin/g3401_3500/s3454_separate_squares_ii/Solution.kt b/src/main/kotlin/g3401_3500/s3454_separate_squares_ii/Solution.kt new file mode 100644 index 000000000..f0b5a5694 --- /dev/null +++ b/src/main/kotlin/g3401_3500/s3454_separate_squares_ii/Solution.kt @@ -0,0 +1,160 @@ +package g3401_3500.s3454_separate_squares_ii + +// #Hard #Array #Binary_Search #Segment_Tree #Line_Sweep +// #2025_02_18_Time_277_ms_(100.00%)_Space_96.52_MB_(33.33%) + +class Solution { + fun separateSquares(squares: Array): Double { + val n = squares.size + val m = 2 * n + val events = createEvents(squares, m) + val xsRaw = createXsRaw(squares, m) + events.sortWith { a, b: Event -> a.y.compareTo(b.y) } + val xs = compress(xsRaw) + val totalUnionArea = calculateTotalUnionArea(events, xs, m) + val target = totalUnionArea / 2.0 + return findSplitPoint(events, xs, m, target) + } + + private fun createEvents(squares: Array, m: Int): Array { + val events = Array(m) { Event(0.0, 0.0, 0.0, 0) } + var idx = 0 + for (sq in squares) { + val x = sq[0].toDouble() + val y = sq[1].toDouble() + val l = sq[2].toDouble() + val x2 = x + l + val y2 = y + l + events[idx++] = Event(y, x, x2, 1) + events[idx++] = Event(y2, x, x2, -1) + } + return events + } + + private fun createXsRaw(squares: Array, m: Int): DoubleArray { + val xsRaw = DoubleArray(m) + var xIdx = 0 + for (sq in squares) { + val x = sq[0].toDouble() + val l = sq[2].toDouble() + xsRaw[xIdx++] = x + xsRaw[xIdx++] = x + l + } + return xsRaw + } + + private fun calculateTotalUnionArea(events: Array, xs: DoubleArray, m: Int): Double { + val segTree = SegmentTree(xs) + var totalUnionArea = 0.0 + var lastY = events[0].y + var i = 0 + while (i < m) { + val curY = events[i].y + if (curY > lastY) { + val unionX = segTree.query() + totalUnionArea += unionX * (curY - lastY) + lastY = curY + } + while (i < m && events[i].y == curY) { + val indices = findIndices(xs, events[i]) + segTree.update(1, 0, xs.size - 1, indices[0], indices[1], events[i].type) + i++ + } + } + return totalUnionArea + } + + private fun findSplitPoint(events: Array, xs: DoubleArray, m: Int, target: Double): Double { + val segTree = SegmentTree(xs) + var lastY = events[0].y + var cumArea = 0.0 + var i = 0 + while (i < m) { + val curY = events[i].y + if (curY > lastY) { + val unionX = segTree.query() + val dy = curY - lastY + if (cumArea + unionX * dy >= target - 1e-10) { + return lastY + (target - cumArea) / unionX + } + cumArea += unionX * dy + lastY = curY + } + while (i < m && events[i].y == curY) { + val indices = findIndices(xs, events[i]) + segTree.update(1, 0, xs.size - 1, indices[0], indices[1], events[i].type) + i++ + } + } + return lastY + } + + private fun findIndices(xs: DoubleArray, event: Event): IntArray { + var lIdx = xs.binarySearch(event.x1) + if (lIdx < 0) { + lIdx = -lIdx - 1 + } + var rIdx = xs.binarySearch(event.x2) + if (rIdx < 0) { + rIdx = -rIdx - 1 + } + return intArrayOf(lIdx, rIdx) + } + + private fun compress(arr: DoubleArray): DoubleArray { + arr.sort() + var cnt = 1 + for (i in 1..= r) { + return + } + if (ql <= l && r <= qr) { + count[idx] += `val` + } else { + val mid = (l + r) shr 1 + update(idx shl 1, l, mid, ql, qr, `val`) + update(idx shl 1 or 1, mid, r, ql, qr, `val`) + } + if (count[idx] > 0) { + tree[idx] = xs[r] - xs[l] + } else if (r - l == 1) { + tree[idx] = 0.0 + } else { + tree[idx] = tree[idx shl 1] + tree[idx shl 1 or 1] + } + } + + fun query(): Double { + return tree[1] + } + } +} diff --git a/src/main/kotlin/g3401_3500/s3454_separate_squares_ii/readme.md b/src/main/kotlin/g3401_3500/s3454_separate_squares_ii/readme.md new file mode 100644 index 000000000..741da7dce --- /dev/null +++ b/src/main/kotlin/g3401_3500/s3454_separate_squares_ii/readme.md @@ -0,0 +1,43 @@ +3454\. Separate Squares II + +Hard + +You are given a 2D integer array `squares`. Each squares[i] = [xi, yi, li] represents the coordinates of the bottom-left point and the side length of a square parallel to the x-axis. + +Find the **minimum** y-coordinate value of a horizontal line such that the total area covered by squares above the line _equals_ the total area covered by squares below the line. + +Answers within 10-5 of the actual answer will be accepted. + +**Note**: Squares **may** overlap. Overlapping areas should be counted **only once** in this version. + +**Example 1:** + +**Input:** squares = [[0,0,1],[2,2,1]] + +**Output:** 1.00000 + +**Explanation:** + +![](https://assets.leetcode.com/uploads/2025/01/15/4065example1drawio.png) + +Any horizontal line between `y = 1` and `y = 2` results in an equal split, with 1 square unit above and 1 square unit below. The minimum y-value is 1. + +**Example 2:** + +**Input:** squares = [[0,0,2],[1,1,1]] + +**Output:** 1.00000 + +**Explanation:** + +![](https://assets.leetcode.com/uploads/2025/01/15/4065example2drawio.png) + +Since the blue square overlaps with the red square, it will not be counted again. Thus, the line `y = 1` splits the squares into two equal parts. + +**Constraints:** + +* 1 <= squares.length <= 5 * 104 +* squares[i] = [xi, yi, li] +* `squares[i].length == 3` +* 0 <= xi, yi <= 109 +* 1 <= li <= 109 \ No newline at end of file diff --git a/src/main/kotlin/g3401_3500/s3455_shortest_matching_substring/Solution.kt b/src/main/kotlin/g3401_3500/s3455_shortest_matching_substring/Solution.kt new file mode 100644 index 000000000..ce2dfd3fb --- /dev/null +++ b/src/main/kotlin/g3401_3500/s3455_shortest_matching_substring/Solution.kt @@ -0,0 +1,108 @@ +package g3401_3500.s3455_shortest_matching_substring + +// #Hard #String #Binary_Search #Two_Pointers #String_Matching +// #2025_02_18_Time_100_ms_(100.00%)_Space_52.17_MB_(100.00%) + +import kotlin.math.min + +class Solution { + private fun getMatch(s: String, p: String): MutableList { + val n = s.length + val m = p.length + val next = IntArray(m) + next.fill(-1) + var i = 1 + var j = -1 + while (i < m) { + while (j != -1 && p[i] != p[j + 1]) { + j = next[j] + } + if (p[i] == p[j + 1]) { + ++j + } + next[i] = j + ++i + } + val match: MutableList = ArrayList() + i = 0 + j = -1 + while (i < n) { + while (j != -1 && s[i] != p[j + 1]) { + j = next[j] + } + if (s[i] == p[j + 1]) { + ++j + } + if (j == m - 1) { + match.add(i - m + 1) + j = next[j] + } + ++i + } + return match + } + + fun shortestMatchingSubstring(s: String, p: String): Int { + val n = s.length + val m = p.length + val d = intArrayOf(-1, -1, -1, m) + for (i in 0.. = ArrayList() + for (i in 0..2) { + if (d[i] + 1 < d[i + 1]) { + subs.add(p.substring(d[i] + 1, d[i + 1])) + } + } + val size = subs.size + if (size == 0) { + return 0 + } + val matches: MutableList> = ArrayList>() + for (sub in subs) { + matches.add(getMatch(s, sub)) + } + var ans = Int.Companion.MAX_VALUE + val ids = IntArray(size) + ids.fill(0) + while (ids[size - 1] < matches[size - 1].size) { + for (i in size - 2 downTo 0) { + while (ids[i] + 1 < matches[i].size && + ( + matches[i][ids[i] + 1] + subs[i].length + <= matches[i + 1][ids[i + 1]] + ) + ) { + ++ids[i] + } + } + var valid = true + for (i in size - 2 downTo 0) { + if (ids[i] >= matches[i].size || + ( + matches[i][ids[i]] + subs[i].length + > matches[i + 1][ids[i + 1]] + ) + ) { + valid = false + break + } + } + if (valid) { + ans = min( + ans, + ( + matches[size - 1][ids[size - 1]] + + subs[size - 1].length - + matches[0][ids[0]] + ), + ) + } + ids[size - 1]++ + } + return if (ans > n) -1 else ans + } +} diff --git a/src/main/kotlin/g3401_3500/s3455_shortest_matching_substring/readme.md b/src/main/kotlin/g3401_3500/s3455_shortest_matching_substring/readme.md new file mode 100644 index 000000000..988440eca --- /dev/null +++ b/src/main/kotlin/g3401_3500/s3455_shortest_matching_substring/readme.md @@ -0,0 +1,58 @@ +3455\. Shortest Matching Substring + +Hard + +You are given a string `s` and a pattern string `p`, where `p` contains **exactly two** `'*'` characters. + +The `'*'` in `p` matches any sequence of zero or more characters. + +Return the length of the **shortest** **substring** in `s` that matches `p`. If there is no such substring, return -1. + +**Note:** The empty substring is considered valid. + +**Example 1:** + +**Input:** s = "abaacbaecebce", p = "ba\*c\*ce" + +**Output:** 8 + +**Explanation:** + +The shortest matching substring of `p` in `s` is "**ba**e**c**eb**ce**". + +**Example 2:** + +**Input:** s = "baccbaadbc", p = "cc\*baa\*adb" + +**Output:** \-1 + +**Explanation:** + +There is no matching substring in `s`. + +**Example 3:** + +**Input:** s = "a", p = "\*\*" + +**Output:** 0 + +**Explanation:** + +The empty substring is the shortest matching substring. + +**Example 4:** + +**Input:** s = "madlogic", p = "\*adlogi\*" + +**Output:** 6 + +**Explanation:** + +The shortest matching substring of `p` in `s` is "**adlogi**". + +**Constraints:** + +* 1 <= s.length <= 105 +* 2 <= p.length <= 105 +* `s` contains only lowercase English letters. +* `p` contains only lowercase English letters and exactly two `'*'`. \ No newline at end of file diff --git a/src/main/kotlin/g3401_3500/s3456_find_special_substring_of_length_k/Solution.kt b/src/main/kotlin/g3401_3500/s3456_find_special_substring_of_length_k/Solution.kt new file mode 100644 index 000000000..d03fdfbf3 --- /dev/null +++ b/src/main/kotlin/g3401_3500/s3456_find_special_substring_of_length_k/Solution.kt @@ -0,0 +1,35 @@ +package g3401_3500.s3456_find_special_substring_of_length_k + +// #Easy #String #2025_02_18_Time_1_ms_(100.00%)_Space_36.22_MB_(54.84%) + +class Solution { + fun hasSpecialSubstring(s: String, k: Int): Boolean { + var start = 0 + var end = k + while (end <= s.length) { + var flag = false + var i = start + while (i < end - 1) { + if (s[i] != s[i + 1]) { + start++ + end++ + flag = true + break + } + i++ + } + if (flag) { + continue + } + if (start - 1 >= 0 && s[start] == s[start - 1] || + end < s.length && s[end] == s[end - 1] + ) { + start++ + end++ + } else { + return true + } + } + return false + } +} diff --git a/src/main/kotlin/g3401_3500/s3456_find_special_substring_of_length_k/readme.md b/src/main/kotlin/g3401_3500/s3456_find_special_substring_of_length_k/readme.md new file mode 100644 index 000000000..32c7b48c8 --- /dev/null +++ b/src/main/kotlin/g3401_3500/s3456_find_special_substring_of_length_k/readme.md @@ -0,0 +1,43 @@ +3456\. Find Special Substring of Length K + +Easy + +You are given a string `s` and an integer `k`. + +Determine if there exists a **substring** of length **exactly** `k` in `s` that satisfies the following conditions: + +1. The substring consists of **only one distinct character** (e.g., `"aaa"` or `"bbb"`). +2. If there is a character **immediately before** the substring, it must be different from the character in the substring. +3. If there is a character **immediately after** the substring, it must also be different from the character in the substring. + +Return `true` if such a substring exists. Otherwise, return `false`. + +**Example 1:** + +**Input:** s = "aaabaaa", k = 3 + +**Output:** true + +**Explanation:** + +The substring `s[4..6] == "aaa"` satisfies the conditions. + +* It has a length of 3. +* All characters are the same. +* The character before `"aaa"` is `'b'`, which is different from `'a'`. +* There is no character after `"aaa"`. + +**Example 2:** + +**Input:** s = "abc", k = 2 + +**Output:** false + +**Explanation:** + +There is no substring of length 2 that consists of one distinct character and satisfies the conditions. + +**Constraints:** + +* `1 <= k <= s.length <= 100` +* `s` consists of lowercase English letters only. \ No newline at end of file diff --git a/src/main/kotlin/g3401_3500/s3457_eat_pizzas/Solution.kt b/src/main/kotlin/g3401_3500/s3457_eat_pizzas/Solution.kt new file mode 100644 index 000000000..a100c012b --- /dev/null +++ b/src/main/kotlin/g3401_3500/s3457_eat_pizzas/Solution.kt @@ -0,0 +1,24 @@ +package g3401_3500.s3457_eat_pizzas + +// #Medium #Array #Sorting #Greedy #2025_02_18_Time_101_ms_(90.91%)_Space_91.06_MB_(63.64%) + +class Solution { + fun maxWeight(pizzas: IntArray): Long { + val n = pizzas.size + val m = n / 4 + val z = (m + 1) / 2 + val y = m / 2 + var j = 0 + pizzas.sort() + var res: Long = 0 + for (i in 0..ith pizza. Every day, you eat **exactly** 4 pizzas. Due to your incredible metabolism, when you eat pizzas of weights `W`, `X`, `Y`, and `Z`, where `W <= X <= Y <= Z`, you gain the weight of only 1 pizza! + +* On **odd-numbered** days **(1-indexed)**, you gain a weight of `Z`. +* On **even-numbered** days, you gain a weight of `Y`. + +Find the **maximum** total weight you can gain by eating **all** pizzas optimally. + +**Note**: It is guaranteed that `n` is a multiple of 4, and each pizza can be eaten only once. + +**Example 1:** + +**Input:** pizzas = [1,2,3,4,5,6,7,8] + +**Output:** 14 + +**Explanation:** + +* On day 1, you eat pizzas at indices `[1, 2, 4, 7] = [2, 3, 5, 8]`. You gain a weight of 8. +* On day 2, you eat pizzas at indices `[0, 3, 5, 6] = [1, 4, 6, 7]`. You gain a weight of 6. + +The total weight gained after eating all the pizzas is `8 + 6 = 14`. + +**Example 2:** + +**Input:** pizzas = [2,1,1,1,1,1,1,1] + +**Output:** 3 + +**Explanation:** + +* On day 1, you eat pizzas at indices `[4, 5, 6, 0] = [1, 1, 1, 2]`. You gain a weight of 2. +* On day 2, you eat pizzas at indices `[1, 2, 3, 7] = [1, 1, 1, 1]`. You gain a weight of 1. + +The total weight gained after eating all the pizzas is `2 + 1 = 3.` + +**Constraints:** + +* 4 <= n == pizzas.length <= 2 * 105 +* 1 <= pizzas[i] <= 105 +* `n` is a multiple of 4. \ No newline at end of file diff --git a/src/main/kotlin/g3401_3500/s3458_select_k_disjoint_special_substrings/Solution.kt b/src/main/kotlin/g3401_3500/s3458_select_k_disjoint_special_substrings/Solution.kt new file mode 100644 index 000000000..c18dd51d6 --- /dev/null +++ b/src/main/kotlin/g3401_3500/s3458_select_k_disjoint_special_substrings/Solution.kt @@ -0,0 +1,49 @@ +package g3401_3500.s3458_select_k_disjoint_special_substrings + +// #Medium #String #Hash_Table #Dynamic_Programming #Sorting #Greedy +// #2025_02_18_Time_24_ms_(100.00%)_Space_39.71_MB_(50.00%) + +class Solution { + fun maxSubstringLength(s: String, k: Int): Boolean { + if (k == 0) return true + val n = s.length + val left = IntArray(26) { n } + val right = IntArray(26) { -1 } + for (i in 0 until n) { + val c = s[i] - 'a' + left[c] = minOf(left[c], i) + right[c] = maxOf(right[c], i) + } + val intervals: MutableList = ArrayList() + for (i in 0 until n) { + if (i != left[s[i] - 'a']) { + continue + } + var end = right[s[i] - 'a'] + var j = i + var valid = true + while (j <= end) { + if (left[s[j] - 'a'] < i) { + valid = false + break + } + end = + maxOf(end, right[s[j] - 'a']) + j++ + } + if (valid && !(i == 0 && end == n - 1)) { + intervals.add(intArrayOf(i, end)) + } + } + intervals.sortBy { it[1] } + var count = 0 + var prev = -1 + for (inter in intervals) { + if (inter[0] > prev) { + count++ + prev = inter[1] + } + } + return count >= k + } +} diff --git a/src/main/kotlin/g3401_3500/s3458_select_k_disjoint_special_substrings/readme.md b/src/main/kotlin/g3401_3500/s3458_select_k_disjoint_special_substrings/readme.md new file mode 100644 index 000000000..139f85290 --- /dev/null +++ b/src/main/kotlin/g3401_3500/s3458_select_k_disjoint_special_substrings/readme.md @@ -0,0 +1,48 @@ +3458\. Select K Disjoint Special Substrings + +Medium + +Given a string `s` of length `n` and an integer `k`, determine whether it is possible to select `k` disjoint **special substrings**. + +A **special substring** is a **substring** where: + +* Any character present inside the substring should not appear outside it in the string. +* The substring is not the entire string `s`. + +**Note** that all `k` substrings must be disjoint, meaning they cannot overlap. + +Return `true` if it is possible to select `k` such disjoint special substrings; otherwise, return `false`. + +**Example 1:** + +**Input:** s = "abcdbaefab", k = 2 + +**Output:** true + +**Explanation:** + +* We can select two disjoint special substrings: `"cd"` and `"ef"`. +* `"cd"` contains the characters `'c'` and `'d'`, which do not appear elsewhere in `s`. +* `"ef"` contains the characters `'e'` and `'f'`, which do not appear elsewhere in `s`. + +**Example 2:** + +**Input:** s = "cdefdc", k = 3 + +**Output:** false + +**Explanation:** + +There can be at most 2 disjoint special substrings: `"e"` and `"f"`. Since `k = 3`, the output is `false`. + +**Example 3:** + +**Input:** s = "abeabe", k = 0 + +**Output:** true + +**Constraints:** + +* 2 <= n == s.length <= 5 * 104 +* `0 <= k <= 26` +* `s` consists only of lowercase English letters. \ No newline at end of file diff --git a/src/main/kotlin/g3401_3500/s3459_length_of_longest_v_shaped_diagonal_segment/Solution.kt b/src/main/kotlin/g3401_3500/s3459_length_of_longest_v_shaped_diagonal_segment/Solution.kt new file mode 100644 index 000000000..588bf6f23 --- /dev/null +++ b/src/main/kotlin/g3401_3500/s3459_length_of_longest_v_shaped_diagonal_segment/Solution.kt @@ -0,0 +1,61 @@ +package g3401_3500.s3459_length_of_longest_v_shaped_diagonal_segment + +// #Hard #Array #Dynamic_Programming #Matrix #Memoization +// #2025_02_18_Time_287_ms_(100.00%)_Space_131.62_MB_(100.00%) + +import kotlin.math.max + +class Solution { + private val ds = arrayOf(intArrayOf(1, 1), intArrayOf(1, -1), intArrayOf(-1, -1), intArrayOf(-1, 1)) + private val nx = intArrayOf(2, 2, 0) + private lateinit var grid: Array + private var n = 0 + private var m = 0 + private lateinit var dp: Array>> + + fun lenOfVDiagonal(g: Array): Int { + this.grid = g + this.n = g.size + this.m = g[0].size + this.dp = + Array>>(n) { Array>(m) { Array(4) { IntArray(2) } } } + for (d1 in dp) { + for (d2 in d1) { + for (d3 in d2) { + d3.fill(-1) + } + } + } + var res = 0 + for (i in 0..= n || j < 0 || j >= m) { + return 0 + } + if (grid[i][j] != x) { + return 0 + } + if (dp[i][j][d][k] != -1) { + return dp[i][j][d][k] + } + var res = dp(i + ds[d][0], j + ds[d][1], nx[x], d, k) + 1 + if (k > 0) { + val d2 = (d + 1) % 4 + val res2 = dp(i + ds[d2][0], j + ds[d2][1], nx[x], d2, 0) + 1 + res = max(res, res2) + } + dp[i][j][d][k] = res + return res + } +} diff --git a/src/main/kotlin/g3401_3500/s3459_length_of_longest_v_shaped_diagonal_segment/readme.md b/src/main/kotlin/g3401_3500/s3459_length_of_longest_v_shaped_diagonal_segment/readme.md new file mode 100644 index 000000000..0745db140 --- /dev/null +++ b/src/main/kotlin/g3401_3500/s3459_length_of_longest_v_shaped_diagonal_segment/readme.md @@ -0,0 +1,71 @@ +3459\. Length of Longest V-Shaped Diagonal Segment + +Hard + +You are given a 2D integer matrix `grid` of size `n x m`, where each element is either `0`, `1`, or `2`. + +A **V-shaped diagonal segment** is defined as: + +* The segment starts with `1`. +* The subsequent elements follow this infinite sequence: `2, 0, 2, 0, ...`. +* The segment: + * Starts **along** a diagonal direction (top-left to bottom-right, bottom-right to top-left, top-right to bottom-left, or bottom-left to top-right). + * Continues the **sequence** in the same diagonal direction. + * Makes **at most one clockwise 90-degree** **turn** to another diagonal direction while **maintaining** the sequence. + +![](https://assets.leetcode.com/uploads/2025/01/11/length_of_longest3.jpg) + +Return the **length** of the **longest** **V-shaped diagonal segment**. If no valid segment _exists_, return 0. + +**Example 1:** + +**Input:** grid = [[2,2,1,2,2],[2,0,2,2,0],[2,0,1,1,0],[1,0,2,2,2],[2,0,0,2,2]] + +**Output:** 5 + +**Explanation:** + +![](https://assets.leetcode.com/uploads/2024/12/09/matrix_1-2.jpg) + +The longest V-shaped diagonal segment has a length of 5 and follows these coordinates: `(0,2) → (1,3) → (2,4)`, takes a **90-degree clockwise turn** at `(2,4)`, and continues as `(3,3) → (4,2)`. + +**Example 2:** + +**Input:** grid = [[2,2,2,2,2],[2,0,2,2,0],[2,0,1,1,0],[1,0,2,2,2],[2,0,0,2,2]] + +**Output:** 4 + +**Explanation:** + +**![](https://assets.leetcode.com/uploads/2024/12/09/matrix_2.jpg)** + +The longest V-shaped diagonal segment has a length of 4 and follows these coordinates: `(2,3) → (3,2)`, takes a **90-degree clockwise turn** at `(3,2)`, and continues as `(2,1) → (1,0)`. + +**Example 3:** + +**Input:** grid = [[1,2,2,2,2],[2,2,2,2,0],[2,0,0,0,0],[0,0,2,2,2],[2,0,0,2,0]] + +**Output:** 5 + +**Explanation:** + +**![](https://assets.leetcode.com/uploads/2024/12/09/matrix_3.jpg)** + +The longest V-shaped diagonal segment has a length of 5 and follows these coordinates: `(0,0) → (1,1) → (2,2) → (3,3) → (4,4)`. + +**Example 4:** + +**Input:** grid = [[1]] + +**Output:** 1 + +**Explanation:** + +The longest V-shaped diagonal segment has a length of 1 and follows these coordinates: `(0,0)`. + +**Constraints:** + +* `n == grid.length` +* `m == grid[i].length` +* `1 <= n, m <= 500` +* `grid[i][j]` is either `0`, `1` or `2`. \ No newline at end of file diff --git a/src/test/kotlin/g3401_3500/s3451_find_invalid_ip_addresses/MysqlTest.kt b/src/test/kotlin/g3401_3500/s3451_find_invalid_ip_addresses/MysqlTest.kt new file mode 100644 index 000000000..1b0f47d01 --- /dev/null +++ b/src/test/kotlin/g3401_3500/s3451_find_invalid_ip_addresses/MysqlTest.kt @@ -0,0 +1,82 @@ +package g3401_3500.s3451_find_invalid_ip_addresses + +import org.hamcrest.CoreMatchers.equalTo +import org.hamcrest.MatcherAssert.assertThat +import org.junit.jupiter.api.Test +import org.zapodot.junit.db.annotations.EmbeddedDatabase +import org.zapodot.junit.db.annotations.EmbeddedDatabaseTest +import org.zapodot.junit.db.common.CompatibilityMode +import java.io.BufferedReader +import java.io.FileNotFoundException +import java.io.FileReader +import java.sql.SQLException +import java.util.stream.Collectors +import javax.sql.DataSource + +@EmbeddedDatabaseTest( + compatibilityMode = CompatibilityMode.MySQL, + initialSqls = [ + ( + " CREATE TABLE logs (" + + " log_id INT," + + " ip VARCHAR(50)," + + " status_code INT" + + ");" + + "insert into logs (log_id, ip, status_code) values " + + "(1, '192.168.1.1', 200);" + + "insert into logs (log_id, ip, status_code) values " + + "(2, '256.1.2.3', 404);" + + "insert into logs (log_id, ip, status_code) values " + + "(3, '192.168.001.1', 200);" + + "insert into logs (log_id, ip, status_code) values " + + "(4, '192.168.1.1', 200);" + + "insert into logs (log_id, ip, status_code) values " + + "(5, '192.168.1', 500);" + + "insert into logs (log_id, ip, status_code) values " + + "(6, '256.1.2.3', 404);" + + "insert into logs (log_id, ip, status_code) values " + + "(7, '192.168.001.1', 200);" + ), + ], +) +internal class MysqlTest { + @Test + @Throws(SQLException::class, FileNotFoundException::class) + fun testScript(@EmbeddedDatabase dataSource: DataSource) { + dataSource.connection.use { connection -> + connection.createStatement().use { statement -> + statement.executeQuery( + BufferedReader( + FileReader( + "src/main/kotlin/g3401_3500/" + + "s3451_find_invalid_ip_addresses/script.sql", + ), + ) + .lines() + .collect(Collectors.joining("\n")) + .replace("#.*?\\r?\\n".toRegex(), ""), + ).use { resultSet -> + assertThat(resultSet.next(), equalTo(true)) + assertThat( + resultSet.getNString(1), + equalTo("256.1.2.3"), + ) + assertThat(resultSet.getNString(2), equalTo("2")) + assertThat(resultSet.next(), equalTo(true)) + assertThat( + resultSet.getNString(1), + equalTo("192.168.001.1"), + ) + assertThat(resultSet.getNString(2), equalTo("2")) + assertThat(resultSet.next(), equalTo(true)) + assertThat( + resultSet.getNString(1), + equalTo("192.168.1"), + ) + assertThat(resultSet.getNString(2), equalTo("1")) + assertThat(resultSet.next(), equalTo(false)) + } + } + } + } +} diff --git a/src/test/kotlin/g3401_3500/s3452_sum_of_good_numbers/SolutionTest.kt b/src/test/kotlin/g3401_3500/s3452_sum_of_good_numbers/SolutionTest.kt new file mode 100644 index 000000000..13cc1d04e --- /dev/null +++ b/src/test/kotlin/g3401_3500/s3452_sum_of_good_numbers/SolutionTest.kt @@ -0,0 +1,20 @@ +package g3401_3500.s3452_sum_of_good_numbers + +import org.hamcrest.CoreMatchers.equalTo +import org.hamcrest.MatcherAssert.assertThat +import org.junit.jupiter.api.Test + +internal class SolutionTest { + @Test + fun sumOfGoodNumbers() { + assertThat( + Solution().sumOfGoodNumbers(intArrayOf(1, 3, 2, 1, 5, 4), 2), + equalTo(12), + ) + } + + @Test + fun sumOfGoodNumbers2() { + assertThat(Solution().sumOfGoodNumbers(intArrayOf(2, 1), 1), equalTo(2)) + } +} diff --git a/src/test/kotlin/g3401_3500/s3453_separate_squares_i/SolutionTest.kt b/src/test/kotlin/g3401_3500/s3453_separate_squares_i/SolutionTest.kt new file mode 100644 index 000000000..a8cbeac09 --- /dev/null +++ b/src/test/kotlin/g3401_3500/s3453_separate_squares_i/SolutionTest.kt @@ -0,0 +1,23 @@ +package g3401_3500.s3453_separate_squares_i + +import org.hamcrest.CoreMatchers.equalTo +import org.hamcrest.MatcherAssert.assertThat +import org.junit.jupiter.api.Test + +internal class SolutionTest { + @Test + fun separateSquares() { + assertThat( + Solution().separateSquares(arrayOf(intArrayOf(0, 0, 1), intArrayOf(2, 2, 1))), + equalTo(1.0), + ) + } + + @Test + fun separateSquares2() { + assertThat( + Solution().separateSquares(arrayOf(intArrayOf(0, 0, 2), intArrayOf(1, 1, 1))), + equalTo(1.1666666666666667), + ) + } +} diff --git a/src/test/kotlin/g3401_3500/s3454_separate_squares_ii/SolutionTest.kt b/src/test/kotlin/g3401_3500/s3454_separate_squares_ii/SolutionTest.kt new file mode 100644 index 000000000..0d1828622 --- /dev/null +++ b/src/test/kotlin/g3401_3500/s3454_separate_squares_ii/SolutionTest.kt @@ -0,0 +1,23 @@ +package g3401_3500.s3454_separate_squares_ii + +import org.hamcrest.CoreMatchers.equalTo +import org.hamcrest.MatcherAssert.assertThat +import org.junit.jupiter.api.Test + +internal class SolutionTest { + @Test + fun separateSquares() { + assertThat( + Solution().separateSquares(arrayOf(intArrayOf(0, 0, 1), intArrayOf(2, 2, 1))), + equalTo(1.0), + ) + } + + @Test + fun separateSquares2() { + assertThat( + Solution().separateSquares(arrayOf(intArrayOf(0, 0, 2), intArrayOf(1, 1, 1))), + equalTo(1.0), + ) + } +} diff --git a/src/test/kotlin/g3401_3500/s3455_shortest_matching_substring/SolutionTest.kt b/src/test/kotlin/g3401_3500/s3455_shortest_matching_substring/SolutionTest.kt new file mode 100644 index 000000000..99bc797d1 --- /dev/null +++ b/src/test/kotlin/g3401_3500/s3455_shortest_matching_substring/SolutionTest.kt @@ -0,0 +1,36 @@ +package g3401_3500.s3455_shortest_matching_substring + +import org.hamcrest.CoreMatchers.equalTo +import org.hamcrest.MatcherAssert.assertThat +import org.junit.jupiter.api.Test + +internal class SolutionTest { + @Test + fun shortestMatchingSubstring() { + assertThat( + Solution().shortestMatchingSubstring("abaacbaecebce", "ba*c*ce"), + equalTo(8), + ) + } + + @Test + fun shortestMatchingSubstring2() { + assertThat( + Solution().shortestMatchingSubstring("baccbaadbc", "cc*baa*adb"), + equalTo(-1), + ) + } + + @Test + fun shortestMatchingSubstring3() { + assertThat(Solution().shortestMatchingSubstring("a", "**"), equalTo(0)) + } + + @Test + fun shortestMatchingSubstring4() { + assertThat( + Solution().shortestMatchingSubstring("madlogic", "*adlogi*"), + equalTo(6), + ) + } +} diff --git a/src/test/kotlin/g3401_3500/s3456_find_special_substring_of_length_k/SolutionTest.kt b/src/test/kotlin/g3401_3500/s3456_find_special_substring_of_length_k/SolutionTest.kt new file mode 100644 index 000000000..684713828 --- /dev/null +++ b/src/test/kotlin/g3401_3500/s3456_find_special_substring_of_length_k/SolutionTest.kt @@ -0,0 +1,31 @@ +package g3401_3500.s3456_find_special_substring_of_length_k + +import org.hamcrest.CoreMatchers.equalTo +import org.hamcrest.MatcherAssert.assertThat +import org.junit.jupiter.api.Test + +internal class SolutionTest { + @Test + fun hasSpecialSubstring() { + assertThat( + Solution().hasSpecialSubstring("aaabaaa", 3), + equalTo(true), + ) + } + + @Test + fun hasSpecialSubstring2() { + assertThat( + Solution().hasSpecialSubstring("abc", 2), + equalTo(false), + ) + } + + @Test + fun hasSpecialSubstring3() { + assertThat( + Solution().hasSpecialSubstring("ccc", 2), + equalTo(false), + ) + } +} diff --git a/src/test/kotlin/g3401_3500/s3457_eat_pizzas/SolutionTest.kt b/src/test/kotlin/g3401_3500/s3457_eat_pizzas/SolutionTest.kt new file mode 100644 index 000000000..fc0629bc7 --- /dev/null +++ b/src/test/kotlin/g3401_3500/s3457_eat_pizzas/SolutionTest.kt @@ -0,0 +1,23 @@ +package g3401_3500.s3457_eat_pizzas + +import org.hamcrest.CoreMatchers.equalTo +import org.hamcrest.MatcherAssert.assertThat +import org.junit.jupiter.api.Test + +internal class SolutionTest { + @Test + fun maxWeight() { + assertThat( + Solution().maxWeight(intArrayOf(1, 2, 3, 4, 5, 6, 7, 8)), + equalTo(14L), + ) + } + + @Test + fun maxWeight2() { + assertThat( + Solution().maxWeight(intArrayOf(2, 1, 1, 1, 1, 1, 1, 1)), + equalTo(3L), + ) + } +} diff --git a/src/test/kotlin/g3401_3500/s3458_select_k_disjoint_special_substrings/SolutionTest.kt b/src/test/kotlin/g3401_3500/s3458_select_k_disjoint_special_substrings/SolutionTest.kt new file mode 100644 index 000000000..21b5d8b3b --- /dev/null +++ b/src/test/kotlin/g3401_3500/s3458_select_k_disjoint_special_substrings/SolutionTest.kt @@ -0,0 +1,31 @@ +package g3401_3500.s3458_select_k_disjoint_special_substrings + +import org.hamcrest.CoreMatchers.equalTo +import org.hamcrest.MatcherAssert.assertThat +import org.junit.jupiter.api.Test + +internal class SolutionTest { + @Test + fun maxSubstringLength() { + assertThat( + Solution().maxSubstringLength("abcdbaefab", 2), + equalTo(true), + ) + } + + @Test + fun maxSubstringLength2() { + assertThat( + Solution().maxSubstringLength("cdefdc", 3), + equalTo(false), + ) + } + + @Test + fun maxSubstringLength3() { + assertThat( + Solution().maxSubstringLength("abeabe", 0), + equalTo(true), + ) + } +} diff --git a/src/test/kotlin/g3401_3500/s3459_length_of_longest_v_shaped_diagonal_segment/SolutionTest.kt b/src/test/kotlin/g3401_3500/s3459_length_of_longest_v_shaped_diagonal_segment/SolutionTest.kt new file mode 100644 index 000000000..853e2a016 --- /dev/null +++ b/src/test/kotlin/g3401_3500/s3459_length_of_longest_v_shaped_diagonal_segment/SolutionTest.kt @@ -0,0 +1,58 @@ +package g3401_3500.s3459_length_of_longest_v_shaped_diagonal_segment + +import org.hamcrest.CoreMatchers.equalTo +import org.hamcrest.MatcherAssert.assertThat +import org.junit.jupiter.api.Test + +internal class SolutionTest { + @Test + fun lenOfVDiagonal() { + assertThat( + Solution() + .lenOfVDiagonal( + arrayOf( + intArrayOf(2, 2, 1, 2, 2), + intArrayOf(2, 0, 2, 2, 0), + intArrayOf(2, 0, 1, 1, 0), + intArrayOf(1, 0, 2, 2, 2), + intArrayOf(2, 0, 0, 2, 2), + ), + ), + equalTo(5), + ) + } + + @Test + fun lenOfVDiagonal2() { + assertThat( + Solution() + .lenOfVDiagonal( + arrayOf( + intArrayOf(2, 2, 2, 2, 2), + intArrayOf(2, 0, 2, 2, 0), + intArrayOf(2, 0, 1, 1, 0), + intArrayOf(1, 0, 2, 2, 2), + intArrayOf(2, 0, 0, 2, 2), + ), + ), + equalTo(4), + ) + } + + @Test + fun lenOfVDiagonal3() { + assertThat( + Solution() + .lenOfVDiagonal( + arrayOf( + intArrayOf(1, 2, 2, 2, 2), + intArrayOf(2, 2, 2, 2, 0), + intArrayOf(2, 0, 0, 0, 0), + intArrayOf(0, 0, 2, 2, 2), + intArrayOf(2, 0, 0, 2, 0), + ), + ), + equalTo(5), + ) + } +}