diff --git a/src/main/java/g3401_3500/s3451_find_invalid_ip_addresses/readme.md b/src/main/java/g3401_3500/s3451_find_invalid_ip_addresses/readme.md new file mode 100644 index 000000000..458a6a95e --- /dev/null +++ b/src/main/java/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/java/g3401_3500/s3451_find_invalid_ip_addresses/script.sql b/src/main/java/g3401_3500/s3451_find_invalid_ip_addresses/script.sql new file mode 100644 index 000000000..7aac57611 --- /dev/null +++ b/src/main/java/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_393_ms_(79.56%)_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/java/g3401_3500/s3452_sum_of_good_numbers/Solution.java b/src/main/java/g3401_3500/s3452_sum_of_good_numbers/Solution.java new file mode 100644 index 000000000..e8ca20098 --- /dev/null +++ b/src/main/java/g3401_3500/s3452_sum_of_good_numbers/Solution.java @@ -0,0 +1,20 @@ +package g3401_3500.s3452_sum_of_good_numbers; + +// #Easy #Array #2025_02_18_Time_1_ms_(99.99%)_Space_44.75_MB_(7.31%) + +public class Solution { + public int sumOfGoodNumbers(int[] nums, int k) { + int totalSum = 0; + int n = nums.length; + for (int i = 0; i < n; i++) { + boolean isGood = i - k < 0 || nums[i] > nums[i - k]; + if (i + k < n && nums[i] <= nums[i + k]) { + isGood = false; + } + if (isGood) { + totalSum += nums[i]; + } + } + return totalSum; + } +} diff --git a/src/main/java/g3401_3500/s3452_sum_of_good_numbers/readme.md b/src/main/java/g3401_3500/s3452_sum_of_good_numbers/readme.md new file mode 100644 index 000000000..f6a899293 --- /dev/null +++ b/src/main/java/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/java/g3401_3500/s3453_separate_squares_i/Solution.java b/src/main/java/g3401_3500/s3453_separate_squares_i/Solution.java new file mode 100644 index 000000000..cd0f4c101 --- /dev/null +++ b/src/main/java/g3401_3500/s3453_separate_squares_i/Solution.java @@ -0,0 +1,34 @@ +package g3401_3500.s3453_separate_squares_i; + +// #Medium #Array #Binary_Search #2025_02_18_Time_60_ms_(99.96%)_Space_88.58_MB_(26.92%) + +public class Solution { + public double separateSquares(int[][] squares) { + long hi = 0L; + long lo = 1_000_000_000L; + for (int[] q : squares) { + lo = Math.min(lo, q[1]); + hi = Math.max(hi, q[1] + (long) q[2]); + } + while (lo <= hi) { + long mid = (lo + hi) / 2; + if (diff(mid, squares) <= 0) { + hi = mid - 1; + } else { + lo = mid + 1; + } + } + double diff1 = diff(hi, squares); + double diff2 = diff(lo, squares); + return hi + diff1 / (diff1 - diff2); + } + + private double diff(long mid, int[][] squares) { + double[] res = new double[2]; + for (int[] q : squares) { + res[0] += Math.min(q[2], Math.max(0, mid - q[1])) * q[2]; + res[1] += Math.min(q[2], Math.max(0, q[1] + q[2] - mid)) * q[2]; + } + return res[1] - res[0]; + } +} diff --git a/src/main/java/g3401_3500/s3453_separate_squares_i/readme.md b/src/main/java/g3401_3500/s3453_separate_squares_i/readme.md new file mode 100644 index 000000000..19f128d6e --- /dev/null +++ b/src/main/java/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/java/g3401_3500/s3454_separate_squares_ii/Solution.java b/src/main/java/g3401_3500/s3454_separate_squares_ii/Solution.java new file mode 100644 index 000000000..c8533f2b7 --- /dev/null +++ b/src/main/java/g3401_3500/s3454_separate_squares_ii/Solution.java @@ -0,0 +1,155 @@ +package g3401_3500.s3454_separate_squares_ii; + +// #Hard #Array #Binary_Search #Segment_Tree #Line_Sweep +// #2025_02_18_Time_156_ms_(80.18%)_Space_79.96_MB_(64.32%) + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +@SuppressWarnings("java:S1210") +public class Solution { + private static class Event implements Comparable { + double y; + int x1; + int x2; + int type; + + Event(double y, int x1, int x2, int type) { + this.y = y; + this.x1 = x1; + this.x2 = x2; + this.type = type; + } + + public int compareTo(Event other) { + return Double.compare(this.y, other.y); + } + } + + private static class Segment { + double y1; + double y2; + double unionX; + double cumArea; + + Segment(double y1, double y2, double unionX, double cumArea) { + this.y1 = y1; + this.y2 = y2; + this.unionX = unionX; + this.cumArea = cumArea; + } + } + + private static class SegmentTree { + int[] count; + double[] len; + int n; + int[] x; + + SegmentTree(int[] x) { + this.x = x; + n = x.length - 1; + count = new int[4 * n]; + len = new double[4 * n]; + } + + void update(int idx, int l, int r, int ql, int qr, int val) { + if (qr < l || ql > r) { + return; + } + if (ql <= l && r <= qr) { + count[idx] += val; + } else { + int mid = (l + r) / 2; + update(2 * idx + 1, l, mid, ql, qr, val); + update(2 * idx + 2, mid + 1, r, ql, qr, val); + } + if (count[idx] > 0) { + len[idx] = x[r + 1] - (double) x[l]; + } else { + if (l == r) { + len[idx] = 0; + } else { + len[idx] = len[2 * idx + 1] + len[2 * idx + 2]; + } + } + } + + void update(int ql, int qr, int val) { + update(0, 0, n - 1, ql, qr, val); + } + + double query() { + return len[0]; + } + } + + public double separateSquares(int[][] squares) { + int n = squares.length; + Event[] events = new Event[2 * n]; + int idx = 0; + List xList = new ArrayList<>(); + for (int[] s : squares) { + int x = s[0]; + int y = s[1]; + int l = s[2]; + int x2 = x + l; + int y2 = y + l; + events[idx++] = new Event(y, x, x2, 1); + events[idx++] = new Event(y2, x, x2, -1); + xList.add(x); + xList.add(x2); + } + Arrays.sort(events); + int m = xList.size(); + int[] xCords = new int[m]; + for (int i = 0; i < m; i++) { + xCords[i] = xList.get(i); + } + Arrays.sort(xCords); + int uniqueCount = 0; + for (int i = 0; i < m; i++) { + if (i == 0 || xCords[i] != xCords[i - 1]) { + xCords[uniqueCount++] = xCords[i]; + } + } + int[] x = Arrays.copyOf(xCords, uniqueCount); + SegmentTree segTree = new SegmentTree(x); + List segments = new ArrayList<>(); + double cumArea = 0.0; + double lastY = events[0].y; + int iEvent = 0; + while (iEvent < events.length) { + double currentY = events[iEvent].y; + double delta = currentY - lastY; + if (delta > 0) { + double unionX = segTree.query(); + segments.add(new Segment(lastY, currentY, unionX, cumArea)); + cumArea += unionX * delta; + } + while (iEvent < events.length && events[iEvent].y == currentY) { + Event e = events[iEvent]; + int left = Arrays.binarySearch(x, e.x1); + int right = Arrays.binarySearch(x, e.x2); + if (left < right) { + segTree.update(left, right - 1, e.type); + } + iEvent++; + } + lastY = currentY; + } + double totalArea = cumArea; + double target = totalArea / 2.0; + double answer; + for (Segment seg : segments) { + double segArea = seg.unionX * (seg.y2 - seg.y1); + if (seg.cumArea + segArea >= target) { + double needed = target - seg.cumArea; + answer = seg.y1 + needed / seg.unionX; + return answer; + } + } + return lastY; + } +} diff --git a/src/main/java/g3401_3500/s3454_separate_squares_ii/readme.md b/src/main/java/g3401_3500/s3454_separate_squares_ii/readme.md new file mode 100644 index 000000000..741da7dce --- /dev/null +++ b/src/main/java/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/java/g3401_3500/s3455_shortest_matching_substring/Solution.java b/src/main/java/g3401_3500/s3455_shortest_matching_substring/Solution.java new file mode 100644 index 000000000..23b36f95f --- /dev/null +++ b/src/main/java/g3401_3500/s3455_shortest_matching_substring/Solution.java @@ -0,0 +1,102 @@ +package g3401_3500.s3455_shortest_matching_substring; + +// #Hard #String #Binary_Search #Two_Pointers #String_Matching +// #2025_02_18_Time_116_ms_(81.44%)_Space_55.28_MB_(88.02%) + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +public class Solution { + private List getMatch(String s, String p) { + int n = s.length(); + int m = p.length(); + int[] next = new int[m]; + Arrays.fill(next, -1); + int i = 1; + int j = -1; + while (i < m) { + while (j != -1 && p.charAt(i) != p.charAt(j + 1)) { + j = next[j]; + } + if (p.charAt(i) == p.charAt(j + 1)) { + ++j; + } + next[i] = j; + ++i; + } + List match = new ArrayList<>(); + i = 0; + j = -1; + while (i < n) { + while (j != -1 && s.charAt(i) != p.charAt(j + 1)) { + j = next[j]; + } + if (s.charAt(i) == p.charAt(j + 1)) { + ++j; + } + if (j == m - 1) { + match.add(i - m + 1); + j = next[j]; + } + ++i; + } + return match; + } + + public int shortestMatchingSubstring(String s, String p) { + int n = s.length(); + int m = p.length(); + int[] d = {-1, -1, -1, m}; + for (int i = 0; i < m; ++i) { + if (p.charAt(i) == '*') { + d[d[1] == -1 ? 1 : 2] = i; + } + } + List subs = new ArrayList<>(); + for (int i = 0; i < 3; ++i) { + if (d[i] + 1 < d[i + 1]) { + subs.add(p.substring(d[i] + 1, d[i + 1])); + } + } + int size = subs.size(); + if (size == 0) { + return 0; + } + List> matches = new ArrayList<>(); + for (String sub : subs) { + matches.add(getMatch(s, sub)); + } + int ans = Integer.MAX_VALUE; + int[] ids = new int[size]; + Arrays.fill(ids, 0); + while (ids[size - 1] < matches.get(size - 1).size()) { + for (int i = size - 2; i >= 0; --i) { + while (ids[i] + 1 < matches.get(i).size() + && matches.get(i).get(ids[i] + 1) + subs.get(i).length() + <= matches.get(i + 1).get(ids[i + 1])) { + ++ids[i]; + } + } + boolean valid = true; + for (int i = size - 2; i >= 0; --i) { + if (ids[i] >= matches.get(i).size() + || matches.get(i).get(ids[i]) + subs.get(i).length() + > matches.get(i + 1).get(ids[i + 1])) { + valid = false; + break; + } + } + if (valid) { + ans = + Math.min( + ans, + matches.get(size - 1).get(ids[size - 1]) + + subs.get(size - 1).length() + - matches.get(0).get(ids[0])); + } + ids[size - 1]++; + } + return ans > n ? -1 : ans; + } +} diff --git a/src/main/java/g3401_3500/s3455_shortest_matching_substring/readme.md b/src/main/java/g3401_3500/s3455_shortest_matching_substring/readme.md new file mode 100644 index 000000000..988440eca --- /dev/null +++ b/src/main/java/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/java/g3401_3500/s3456_find_special_substring_of_length_k/Solution.java b/src/main/java/g3401_3500/s3456_find_special_substring_of_length_k/Solution.java new file mode 100644 index 000000000..b49eda195 --- /dev/null +++ b/src/main/java/g3401_3500/s3456_find_special_substring_of_length_k/Solution.java @@ -0,0 +1,33 @@ +package g3401_3500.s3456_find_special_substring_of_length_k; + +// #Easy #String #2025_02_18_Time_0_ms_(100.00%)_Space_41.93_MB_(99.07%) + +@SuppressWarnings("java:S1871") +public class Solution { + public boolean hasSpecialSubstring(String s, int k) { + int start = 0; + int end = k; + while (end <= s.length()) { + boolean flag = false; + for (int i = start; i < end - 1; i++) { + if (s.charAt(i) != s.charAt(i + 1)) { + start++; + end++; + flag = true; + break; + } + } + if (flag) { + continue; + } + if (start - 1 >= 0 && s.charAt(start) == s.charAt(start - 1) + || end < s.length() && s.charAt(end) == s.charAt(end - 1)) { + start++; + end++; + } else { + return true; + } + } + return false; + } +} diff --git a/src/main/java/g3401_3500/s3456_find_special_substring_of_length_k/readme.md b/src/main/java/g3401_3500/s3456_find_special_substring_of_length_k/readme.md new file mode 100644 index 000000000..32c7b48c8 --- /dev/null +++ b/src/main/java/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/java/g3401_3500/s3457_eat_pizzas/Solution.java b/src/main/java/g3401_3500/s3457_eat_pizzas/Solution.java new file mode 100644 index 000000000..de35a7396 --- /dev/null +++ b/src/main/java/g3401_3500/s3457_eat_pizzas/Solution.java @@ -0,0 +1,26 @@ +package g3401_3500.s3457_eat_pizzas; + +// #Medium #Array #Sorting #Greedy #2025_02_18_Time_63_ms_(40.14%)_Space_81.02_MB_(36.94%) + +import java.util.Arrays; + +public class Solution { + public long maxWeight(int[] pizzas) { + int n = pizzas.length; + int m = n / 4; + int z = (m + 1) / 2; + int y = m / 2; + int j = 0; + Arrays.sort(pizzas); + long res = 0; + for (int i = 0; i < z; ++i) { + res += pizzas[n - 1 - j]; + j += 1; + } + for (int i = 0; i < y; ++i) { + res += pizzas[n - 1 - j - 1]; + j += 2; + } + return res; + } +} diff --git a/src/main/java/g3401_3500/s3457_eat_pizzas/readme.md b/src/main/java/g3401_3500/s3457_eat_pizzas/readme.md new file mode 100644 index 000000000..fa6b270b8 --- /dev/null +++ b/src/main/java/g3401_3500/s3457_eat_pizzas/readme.md @@ -0,0 +1,44 @@ +3457\. Eat Pizzas! + +Medium + +You are given an integer array `pizzas` of size `n`, where `pizzas[i]` represents the weight of the 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/java/g3401_3500/s3458_select_k_disjoint_special_substrings/Solution.java b/src/main/java/g3401_3500/s3458_select_k_disjoint_special_substrings/Solution.java new file mode 100644 index 000000000..7af2bd875 --- /dev/null +++ b/src/main/java/g3401_3500/s3458_select_k_disjoint_special_substrings/Solution.java @@ -0,0 +1,58 @@ +package g3401_3500.s3458_select_k_disjoint_special_substrings; + +// #Medium #String #Hash_Table #Dynamic_Programming #Sorting #Greedy +// #2025_02_18_Time_7_ms_(95.31%)_Space_45.21_MB_(87.79%) + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +public class Solution { + public boolean maxSubstringLength(String s, int k) { + int n = s.length(); + if (k == 0) { + return true; + } + int[] first = new int[26]; + int[] last = new int[26]; + Arrays.fill(first, n); + Arrays.fill(last, -1); + for (int i = 0; i < n; i++) { + int c = s.charAt(i) - 'a'; + first[c] = Math.min(first[c], i); + last[c] = i; + } + List intervals = new ArrayList<>(); + for (int c = 0; c < 26; c++) { + if (last[c] == -1) { + continue; + } + int start = first[c]; + int end = last[c]; + int j = start; + boolean valid = true; + while (j <= end) { + int cur = s.charAt(j) - 'a'; + if (first[cur] < start) { + valid = false; + break; + } + end = Math.max(end, last[cur]); + j++; + } + if (valid && !(start == 0 && end == n - 1)) { + intervals.add(new int[] {start, end}); + } + } + intervals.sort((a, b) -> Integer.compare(a[1], b[1])); + int count = 0; + int prevEnd = -1; + for (int[] interval : intervals) { + if (interval[0] > prevEnd) { + count++; + prevEnd = interval[1]; + } + } + return count >= k; + } +} diff --git a/src/main/java/g3401_3500/s3458_select_k_disjoint_special_substrings/readme.md b/src/main/java/g3401_3500/s3458_select_k_disjoint_special_substrings/readme.md new file mode 100644 index 000000000..139f85290 --- /dev/null +++ b/src/main/java/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/java/g3401_3500/s3459_length_of_longest_v_shaped_diagonal_segment/Solution.java b/src/main/java/g3401_3500/s3459_length_of_longest_v_shaped_diagonal_segment/Solution.java new file mode 100644 index 000000000..013814405 --- /dev/null +++ b/src/main/java/g3401_3500/s3459_length_of_longest_v_shaped_diagonal_segment/Solution.java @@ -0,0 +1,60 @@ +package g3401_3500.s3459_length_of_longest_v_shaped_diagonal_segment; + +// #Hard #Array #Dynamic_Programming #Matrix #Memoization +// #2025_02_18_Time_461_ms_(36.09%)_Space_127.47_MB_(39.48%) + +import java.util.Arrays; + +public class Solution { + private final int[][] ds = {{1, 1}, {1, -1}, {-1, -1}, {-1, 1}}; + private final int[] nx = {2, 2, 0}; + private int[][] grid; + private int n; + private int m; + private int[][][][] dp; + + public int lenOfVDiagonal(int[][] g) { + this.grid = g; + this.n = g.length; + this.m = g[0].length; + this.dp = new int[n][m][4][2]; + for (int[][][] d1 : dp) { + for (int[][] d2 : d1) { + for (int[] d3 : d2) { + Arrays.fill(d3, -1); + } + } + } + int res = 0; + for (int i = 0; i < n; i++) { + for (int j = 0; j < m; j++) { + if (g[i][j] == 1) { + for (int d = 0; d < 4; d++) { + res = Math.max(res, dp(i, j, 1, d, 1)); + } + } + } + } + return res; + } + + private int dp(int i, int j, int x, int d, int k) { + if (i < 0 || i >= 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]; + } + int res = dp(i + ds[d][0], j + ds[d][1], nx[x], d, k) + 1; + if (k > 0) { + int d2 = (d + 1) % 4; + int res2 = dp(i + ds[d2][0], j + ds[d2][1], nx[x], d2, 0) + 1; + res = Math.max(res, res2); + } + dp[i][j][d][k] = res; + return res; + } +} diff --git a/src/main/java/g3401_3500/s3459_length_of_longest_v_shaped_diagonal_segment/readme.md b/src/main/java/g3401_3500/s3459_length_of_longest_v_shaped_diagonal_segment/readme.md new file mode 100644 index 000000000..0745db140 --- /dev/null +++ b/src/main/java/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/java/g3401_3500/s3451_find_invalid_ip_addresses/MysqlTest.java b/src/test/java/g3401_3500/s3451_find_invalid_ip_addresses/MysqlTest.java new file mode 100644 index 000000000..dc31567fe --- /dev/null +++ b/src/test/java/g3401_3500/s3451_find_invalid_ip_addresses/MysqlTest.java @@ -0,0 +1,70 @@ +package g3401_3500.s3451_find_invalid_ip_addresses; + +import static org.hamcrest.CoreMatchers.equalTo; +import static org.hamcrest.MatcherAssert.assertThat; + +import java.io.BufferedReader; +import java.io.FileNotFoundException; +import java.io.FileReader; +import java.sql.Connection; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Statement; +import java.util.stream.Collectors; +import javax.sql.DataSource; +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; + +@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);") +class MysqlTest { + @Test + void testScript(@EmbeddedDatabase DataSource dataSource) + throws SQLException, FileNotFoundException { + try (final Connection connection = dataSource.getConnection()) { + try (final Statement statement = connection.createStatement(); + final ResultSet resultSet = + statement.executeQuery( + new BufferedReader( + new FileReader( + "src/main/java/g3401_3500/" + + "s3451_find_invalid_ip_addresses/script.sql")) + .lines() + .collect(Collectors.joining("\n")) + .replaceAll("#.*?\\r?\\n", ""))) { + 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/java/g3401_3500/s3452_sum_of_good_numbers/SolutionTest.java b/src/test/java/g3401_3500/s3452_sum_of_good_numbers/SolutionTest.java new file mode 100644 index 000000000..e70f1b84f --- /dev/null +++ b/src/test/java/g3401_3500/s3452_sum_of_good_numbers/SolutionTest.java @@ -0,0 +1,18 @@ +package g3401_3500.s3452_sum_of_good_numbers; + +import static org.hamcrest.CoreMatchers.equalTo; +import static org.hamcrest.MatcherAssert.assertThat; + +import org.junit.jupiter.api.Test; + +class SolutionTest { + @Test + void sumOfGoodNumbers() { + assertThat(new Solution().sumOfGoodNumbers(new int[] {1, 3, 2, 1, 5, 4}, 2), equalTo(12)); + } + + @Test + void sumOfGoodNumbers2() { + assertThat(new Solution().sumOfGoodNumbers(new int[] {2, 1}, 1), equalTo(2)); + } +} diff --git a/src/test/java/g3401_3500/s3453_separate_squares_i/SolutionTest.java b/src/test/java/g3401_3500/s3453_separate_squares_i/SolutionTest.java new file mode 100644 index 000000000..cd65874ce --- /dev/null +++ b/src/test/java/g3401_3500/s3453_separate_squares_i/SolutionTest.java @@ -0,0 +1,21 @@ +package g3401_3500.s3453_separate_squares_i; + +import static org.hamcrest.CoreMatchers.equalTo; +import static org.hamcrest.MatcherAssert.assertThat; + +import org.junit.jupiter.api.Test; + +class SolutionTest { + @Test + void separateSquares() { + assertThat( + new Solution().separateSquares(new int[][] {{0, 0, 1}, {2, 2, 1}}), equalTo(1.0)); + } + + @Test + void separateSquares2() { + assertThat( + new Solution().separateSquares(new int[][] {{0, 0, 2}, {1, 1, 1}}), + equalTo(1.1666666666666667)); + } +} diff --git a/src/test/java/g3401_3500/s3454_separate_squares_ii/SolutionTest.java b/src/test/java/g3401_3500/s3454_separate_squares_ii/SolutionTest.java new file mode 100644 index 000000000..6d9140e95 --- /dev/null +++ b/src/test/java/g3401_3500/s3454_separate_squares_ii/SolutionTest.java @@ -0,0 +1,20 @@ +package g3401_3500.s3454_separate_squares_ii; + +import static org.hamcrest.CoreMatchers.equalTo; +import static org.hamcrest.MatcherAssert.assertThat; + +import org.junit.jupiter.api.Test; + +class SolutionTest { + @Test + void separateSquares() { + assertThat( + new Solution().separateSquares(new int[][] {{0, 0, 1}, {2, 2, 1}}), equalTo(1.0D)); + } + + @Test + void separateSquares2() { + assertThat( + new Solution().separateSquares(new int[][] {{0, 0, 2}, {1, 1, 1}}), equalTo(1.0D)); + } +} diff --git a/src/test/java/g3401_3500/s3455_shortest_matching_substring/SolutionTest.java b/src/test/java/g3401_3500/s3455_shortest_matching_substring/SolutionTest.java new file mode 100644 index 000000000..55139c1e8 --- /dev/null +++ b/src/test/java/g3401_3500/s3455_shortest_matching_substring/SolutionTest.java @@ -0,0 +1,30 @@ +package g3401_3500.s3455_shortest_matching_substring; + +import static org.hamcrest.CoreMatchers.equalTo; +import static org.hamcrest.MatcherAssert.assertThat; + +import org.junit.jupiter.api.Test; + +class SolutionTest { + @Test + void shortestMatchingSubstring() { + assertThat( + new Solution().shortestMatchingSubstring("abaacbaecebce", "ba*c*ce"), equalTo(8)); + } + + @Test + void shortestMatchingSubstring2() { + assertThat( + new Solution().shortestMatchingSubstring("baccbaadbc", "cc*baa*adb"), equalTo(-1)); + } + + @Test + void shortestMatchingSubstring3() { + assertThat(new Solution().shortestMatchingSubstring("a", "**"), equalTo(0)); + } + + @Test + void shortestMatchingSubstring4() { + assertThat(new Solution().shortestMatchingSubstring("madlogic", "*adlogi*"), equalTo(6)); + } +} diff --git a/src/test/java/g3401_3500/s3456_find_special_substring_of_length_k/SolutionTest.java b/src/test/java/g3401_3500/s3456_find_special_substring_of_length_k/SolutionTest.java new file mode 100644 index 000000000..e94179988 --- /dev/null +++ b/src/test/java/g3401_3500/s3456_find_special_substring_of_length_k/SolutionTest.java @@ -0,0 +1,23 @@ +package g3401_3500.s3456_find_special_substring_of_length_k; + +import static org.hamcrest.CoreMatchers.equalTo; +import static org.hamcrest.MatcherAssert.assertThat; + +import org.junit.jupiter.api.Test; + +class SolutionTest { + @Test + void hasSpecialSubstring() { + assertThat(new Solution().hasSpecialSubstring("aaabaaa", 3), equalTo(true)); + } + + @Test + void hasSpecialSubstring2() { + assertThat(new Solution().hasSpecialSubstring("abc", 2), equalTo(false)); + } + + @Test + void hasSpecialSubstring3() { + assertThat(new Solution().hasSpecialSubstring("ccc", 2), equalTo(false)); + } +} diff --git a/src/test/java/g3401_3500/s3457_eat_pizzas/SolutionTest.java b/src/test/java/g3401_3500/s3457_eat_pizzas/SolutionTest.java new file mode 100644 index 000000000..6b9b2f3d6 --- /dev/null +++ b/src/test/java/g3401_3500/s3457_eat_pizzas/SolutionTest.java @@ -0,0 +1,18 @@ +package g3401_3500.s3457_eat_pizzas; + +import static org.hamcrest.CoreMatchers.equalTo; +import static org.hamcrest.MatcherAssert.assertThat; + +import org.junit.jupiter.api.Test; + +class SolutionTest { + @Test + void maxWeight() { + assertThat(new Solution().maxWeight(new int[] {1, 2, 3, 4, 5, 6, 7, 8}), equalTo(14L)); + } + + @Test + void maxWeight2() { + assertThat(new Solution().maxWeight(new int[] {2, 1, 1, 1, 1, 1, 1, 1}), equalTo(3L)); + } +} diff --git a/src/test/java/g3401_3500/s3458_select_k_disjoint_special_substrings/SolutionTest.java b/src/test/java/g3401_3500/s3458_select_k_disjoint_special_substrings/SolutionTest.java new file mode 100644 index 000000000..86d92bdf0 --- /dev/null +++ b/src/test/java/g3401_3500/s3458_select_k_disjoint_special_substrings/SolutionTest.java @@ -0,0 +1,23 @@ +package g3401_3500.s3458_select_k_disjoint_special_substrings; + +import static org.hamcrest.CoreMatchers.equalTo; +import static org.hamcrest.MatcherAssert.assertThat; + +import org.junit.jupiter.api.Test; + +class SolutionTest { + @Test + void maxSubstringLength() { + assertThat(new Solution().maxSubstringLength("abcdbaefab", 2), equalTo(true)); + } + + @Test + void maxSubstringLength2() { + assertThat(new Solution().maxSubstringLength("cdefdc", 3), equalTo(false)); + } + + @Test + void maxSubstringLength3() { + assertThat(new Solution().maxSubstringLength("abeabe", 0), equalTo(true)); + } +} diff --git a/src/test/java/g3401_3500/s3459_length_of_longest_v_shaped_diagonal_segment/SolutionTest.java b/src/test/java/g3401_3500/s3459_length_of_longest_v_shaped_diagonal_segment/SolutionTest.java new file mode 100644 index 000000000..4b681dd61 --- /dev/null +++ b/src/test/java/g3401_3500/s3459_length_of_longest_v_shaped_diagonal_segment/SolutionTest.java @@ -0,0 +1,53 @@ +package g3401_3500.s3459_length_of_longest_v_shaped_diagonal_segment; + +import static org.hamcrest.CoreMatchers.equalTo; +import static org.hamcrest.MatcherAssert.assertThat; + +import org.junit.jupiter.api.Test; + +class SolutionTest { + @Test + void lenOfVDiagonal() { + assertThat( + new Solution() + .lenOfVDiagonal( + new int[][] { + {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} + }), + equalTo(5)); + } + + @Test + void lenOfVDiagonal2() { + assertThat( + new Solution() + .lenOfVDiagonal( + new int[][] { + {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} + }), + equalTo(4)); + } + + @Test + void lenOfVDiagonal3() { + assertThat( + new Solution() + .lenOfVDiagonal( + new int[][] { + {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} + }), + equalTo(5)); + } +}