diff --git a/src/main/java/g3101_3200/s3163_string_compression_iii/Solution.java b/src/main/java/g3101_3200/s3163_string_compression_iii/Solution.java new file mode 100644 index 000000000..f1f7e3dac --- /dev/null +++ b/src/main/java/g3101_3200/s3163_string_compression_iii/Solution.java @@ -0,0 +1,26 @@ +package g3101_3200.s3163_string_compression_iii; + +// #Medium #String #2024_06_02_Time_17_ms_(88.10%)_Space_45.7_MB_(71.08%) + +public class Solution { + public String compressedString(String word) { + StringBuilder builder = new StringBuilder(); + char last = word.charAt(0); + int count = 1; + for (int i = 1, l = word.length(); i < l; i++) { + if (word.charAt(i) == last) { + count++; + if (count == 10) { + builder.append(9).append(last); + count = 1; + } + } else { + builder.append(count).append(last); + last = word.charAt(i); + count = 1; + } + } + builder.append(count).append(last); + return builder.toString(); + } +} diff --git a/src/main/java/g3101_3200/s3163_string_compression_iii/readme.md b/src/main/java/g3101_3200/s3163_string_compression_iii/readme.md new file mode 100644 index 000000000..05221f34f --- /dev/null +++ b/src/main/java/g3101_3200/s3163_string_compression_iii/readme.md @@ -0,0 +1,42 @@ +3163\. String Compression III + +Medium + +Given a string `word`, compress it using the following algorithm: + +* Begin with an empty string `comp`. While `word` is **not** empty, use the following operation: + * Remove a maximum length prefix of `word` made of a _single character_ `c` repeating **at most** 9 times. + * Append the length of the prefix followed by `c` to `comp`. + +Return the string `comp`. + +**Example 1:** + +**Input:** word = "abcde" + +**Output:** "1a1b1c1d1e" + +**Explanation:** + +Initially, `comp = ""`. Apply the operation 5 times, choosing `"a"`, `"b"`, `"c"`, `"d"`, and `"e"` as the prefix in each operation. + +For each prefix, append `"1"` followed by the character to `comp`. + +**Example 2:** + +**Input:** word = "aaaaaaaaaaaaaabb" + +**Output:** "9a5a2b" + +**Explanation:** + +Initially, `comp = ""`. Apply the operation 3 times, choosing `"aaaaaaaaa"`, `"aaaaa"`, and `"bb"` as the prefix in each operation. + +* For prefix `"aaaaaaaaa"`, append `"9"` followed by `"a"` to `comp`. +* For prefix `"aaaaa"`, append `"5"` followed by `"a"` to `comp`. +* For prefix `"bb"`, append `"2"` followed by `"b"` to `comp`. + +**Constraints:** + +* 1 <= word.length <= 2 * 105 +* `word` consists only of lowercase English letters. \ No newline at end of file diff --git a/src/main/java/g3101_3200/s3164_find_the_number_of_good_pairs_ii/Solution.java b/src/main/java/g3101_3200/s3164_find_the_number_of_good_pairs_ii/Solution.java new file mode 100644 index 000000000..eab02544a --- /dev/null +++ b/src/main/java/g3101_3200/s3164_find_the_number_of_good_pairs_ii/Solution.java @@ -0,0 +1,34 @@ +package g3101_3200.s3164_find_the_number_of_good_pairs_ii; + +// #Medium #Array #Hash_Table #2024_06_02_Time_407_ms_(75.28%)_Space_66.8_MB_(7.30%) + +import java.util.HashMap; + +public class Solution { + public long numberOfPairs(int[] nums1, int[] nums2, int k) { + HashMap hm = new HashMap<>(); + long ans = 0; + for (int val : nums2) { + hm.put(val * k, hm.getOrDefault(val * k, 0) + 1); + } + for (int indx = 0; indx < nums1.length; indx++) { + if (nums1[indx] % k != 0) { + continue; + } + for (int factor = 1; factor * factor <= nums1[indx]; factor++) { + if (nums1[indx] % factor != 0) { + continue; + } + int factor1 = factor; + int factor2 = nums1[indx] / factor; + if (hm.containsKey(factor1)) { + ans += hm.get(factor1); + } + if (factor1 != factor2 && hm.containsKey(factor2)) { + ans += hm.get(factor2); + } + } + } + return ans; + } +} diff --git a/src/main/java/g3101_3200/s3164_find_the_number_of_good_pairs_ii/readme.md b/src/main/java/g3101_3200/s3164_find_the_number_of_good_pairs_ii/readme.md new file mode 100644 index 000000000..49c337b3d --- /dev/null +++ b/src/main/java/g3101_3200/s3164_find_the_number_of_good_pairs_ii/readme.md @@ -0,0 +1,35 @@ +3164\. Find the Number of Good Pairs II + +Medium + +You are given 2 integer arrays `nums1` and `nums2` of lengths `n` and `m` respectively. You are also given a **positive** integer `k`. + +A pair `(i, j)` is called **good** if `nums1[i]` is divisible by `nums2[j] * k` (`0 <= i <= n - 1`, `0 <= j <= m - 1`). + +Return the total number of **good** pairs. + +**Example 1:** + +**Input:** nums1 = [1,3,4], nums2 = [1,3,4], k = 1 + +**Output:** 5 + +**Explanation:** + +The 5 good pairs are `(0, 0)`, `(1, 0)`, `(1, 1)`, `(2, 0)`, and `(2, 2)`. + +**Example 2:** + +**Input:** nums1 = [1,2,4,12], nums2 = [2,4], k = 3 + +**Output:** 2 + +**Explanation:** + +The 2 good pairs are `(3, 0)` and `(3, 1)`. + +**Constraints:** + +* 1 <= n, m <= 105 +* 1 <= nums1[i], nums2[j] <= 106 +* 1 <= k <= 103 \ No newline at end of file diff --git a/src/main/java/g3101_3200/s3165_maximum_sum_of_subsequence_with_non_adjacent_elements/Solution.java b/src/main/java/g3101_3200/s3165_maximum_sum_of_subsequence_with_non_adjacent_elements/Solution.java new file mode 100644 index 000000000..8de741c4b --- /dev/null +++ b/src/main/java/g3101_3200/s3165_maximum_sum_of_subsequence_with_non_adjacent_elements/Solution.java @@ -0,0 +1,125 @@ +package g3101_3200.s3165_maximum_sum_of_subsequence_with_non_adjacent_elements; + +// #Hard #Array #Dynamic_Programming #Divide_and_Conquer #Segment_Tree +// #2024_06_02_Time_1927_ms_(87.75%)_Space_82.1_MB_(5.31%) + +import java.util.stream.Stream; + +public class Solution { + private static final int MOD = 1_000_000_007; + + public int maximumSumSubsequence(int[] nums, int[][] queries) { + int ans = 0; + SegTree segTree = new SegTree(nums); + for (int[] q : queries) { + int idx = q[0]; + int val = q[1]; + segTree.update(idx, val); + ans = (ans + segTree.getMax()) % MOD; + } + return ans; + } + + static class SegTree { + private static class Record { + int takeFirstTakeLast; + int takeFirstSkipLast; + int skipFirstSkipLast; + int skipFirstTakeLast; + + public Integer getMax() { + return Stream.of( + this.takeFirstSkipLast, + this.takeFirstTakeLast, + this.skipFirstSkipLast, + this.skipFirstTakeLast) + .max(Integer::compare) + .orElse(null); + } + + public Integer skipLast() { + return Stream.of(this.takeFirstSkipLast, this.skipFirstSkipLast) + .max(Integer::compare) + .orElse(null); + } + + public Integer takeLast() { + return Stream.of(this.skipFirstTakeLast, this.takeFirstTakeLast) + .max(Integer::compare) + .orElse(null); + } + } + + private final Record[] seg; + private final int[] nums; + + public SegTree(int[] nums) { + this.nums = nums; + seg = new Record[4 * nums.length]; + for (int i = 0; i < 4 * nums.length; ++i) { + seg[i] = new Record(); + } + build(0, nums.length - 1, 0); + } + + private void build(int i, int j, int k) { + if (i == j) { + seg[k].takeFirstTakeLast = nums[i]; + return; + } + int mid = (i + j) >> 1; + build(i, mid, 2 * k + 1); + build(mid + 1, j, 2 * k + 2); + merge(k); + } + + // merge [2*k+1, 2*k+2] into k + private void merge(int k) { + seg[k].takeFirstSkipLast = + Math.max( + seg[2 * k + 1].takeFirstSkipLast + seg[2 * k + 2].skipLast(), + seg[2 * k + 1].takeFirstTakeLast + seg[2 * k + 2].skipFirstSkipLast); + + seg[k].takeFirstTakeLast = + Math.max( + seg[2 * k + 1].takeFirstSkipLast + seg[2 * k + 2].takeLast(), + seg[2 * k + 1].takeFirstTakeLast + seg[2 * k + 2].skipFirstTakeLast); + + seg[k].skipFirstTakeLast = + Math.max( + seg[2 * k + 1].skipFirstSkipLast + seg[2 * k + 2].takeLast(), + seg[2 * k + 1].skipFirstTakeLast + seg[2 * k + 2].skipFirstTakeLast); + + seg[k].skipFirstSkipLast = + Math.max( + seg[2 * k + 1].skipFirstSkipLast + seg[2 * k + 2].skipLast(), + seg[2 * k + 1].skipFirstTakeLast + seg[2 * k + 2].skipFirstSkipLast); + } + + // child -> parent + public void update(int idx, int val) { + int i = 0; + int j = nums.length - 1; + int k = 0; + update(idx, val, k, i, j); + } + + private void update(int idx, int val, int k, int i, int j) { + if (i == j) { + seg[k].takeFirstTakeLast = val; + return; + } + int mid = (i + j) >> 1; + if (idx <= mid) { + update(idx, val, 2 * k + 1, i, mid); + } else { + update(idx, val, 2 * k + 2, mid + 1, j); + } + merge(k); + } + + public int getMax() { + return seg[0].getMax(); + } + } +} diff --git a/src/main/java/g3101_3200/s3165_maximum_sum_of_subsequence_with_non_adjacent_elements/readme.md b/src/main/java/g3101_3200/s3165_maximum_sum_of_subsequence_with_non_adjacent_elements/readme.md new file mode 100644 index 000000000..b02f63314 --- /dev/null +++ b/src/main/java/g3101_3200/s3165_maximum_sum_of_subsequence_with_non_adjacent_elements/readme.md @@ -0,0 +1,41 @@ +3165\. Maximum Sum of Subsequence With Non-adjacent Elements + +Hard + +You are given an array `nums` consisting of integers. You are also given a 2D array `queries`, where queries[i] = [posi, xi]. + +For query `i`, we first set nums[posi] equal to xi, then we calculate the answer to query `i` which is the **maximum** sum of a subsequence of `nums` where **no two adjacent elements are selected**. + +Return the _sum_ of the answers to all queries. + +Since the final answer may be very large, return it **modulo** 109 + 7. + +A **subsequence** is an array that can be derived from another array by deleting some or no elements without changing the order of the remaining elements. + +**Example 1:** + +**Input:** nums = [3,5,9], queries = [[1,-2],[0,-3]] + +**Output:** 21 + +**Explanation:** + After the 1st query, `nums = [3,-2,9]` and the maximum sum of a subsequence with non-adjacent elements is `3 + 9 = 12`. + After the 2nd query, `nums = [-3,-2,9]` and the maximum sum of a subsequence with non-adjacent elements is 9. + +**Example 2:** + +**Input:** nums = [0,-1], queries = [[0,-5]] + +**Output:** 0 + +**Explanation:** + After the 1st query, `nums = [-5,-1]` and the maximum sum of a subsequence with non-adjacent elements is 0 (choosing an empty subsequence). + +**Constraints:** + +* 1 <= nums.length <= 5 * 104 +* -105 <= nums[i] <= 105 +* 1 <= queries.length <= 5 * 104 +* queries[i] == [posi, xi] +* 0 <= posi <= nums.length - 1 +* -105 <= xi <= 105 \ No newline at end of file diff --git a/src/test/java/g3101_3200/s3163_string_compression_iii/SolutionTest.java b/src/test/java/g3101_3200/s3163_string_compression_iii/SolutionTest.java new file mode 100644 index 000000000..3ba5d937b --- /dev/null +++ b/src/test/java/g3101_3200/s3163_string_compression_iii/SolutionTest.java @@ -0,0 +1,18 @@ +package g3101_3200.s3163_string_compression_iii; + +import static org.hamcrest.CoreMatchers.equalTo; +import static org.hamcrest.MatcherAssert.assertThat; + +import org.junit.jupiter.api.Test; + +class SolutionTest { + @Test + void compressedString() { + assertThat(new Solution().compressedString("abcde"), equalTo("1a1b1c1d1e")); + } + + @Test + void compressedString2() { + assertThat(new Solution().compressedString("aaaaaaaaaaaaaabb"), equalTo("9a5a2b")); + } +} diff --git a/src/test/java/g3101_3200/s3164_find_the_number_of_good_pairs_ii/SolutionTest.java b/src/test/java/g3101_3200/s3164_find_the_number_of_good_pairs_ii/SolutionTest.java new file mode 100644 index 000000000..b7d7f3e90 --- /dev/null +++ b/src/test/java/g3101_3200/s3164_find_the_number_of_good_pairs_ii/SolutionTest.java @@ -0,0 +1,22 @@ +package g3101_3200.s3164_find_the_number_of_good_pairs_ii; + +import static org.hamcrest.CoreMatchers.equalTo; +import static org.hamcrest.MatcherAssert.assertThat; + +import org.junit.jupiter.api.Test; + +class SolutionTest { + @Test + void numberOfPairs() { + assertThat( + new Solution().numberOfPairs(new int[] {1, 3, 4}, new int[] {1, 3, 4}, 1), + equalTo(5L)); + } + + @Test + void numberOfPairs2() { + assertThat( + new Solution().numberOfPairs(new int[] {1, 2, 4, 12}, new int[] {2, 4}, 3), + equalTo(2L)); + } +} diff --git a/src/test/java/g3101_3200/s3165_maximum_sum_of_subsequence_with_non_adjacent_elements/SolutionTest.java b/src/test/java/g3101_3200/s3165_maximum_sum_of_subsequence_with_non_adjacent_elements/SolutionTest.java new file mode 100644 index 000000000..d84433a92 --- /dev/null +++ b/src/test/java/g3101_3200/s3165_maximum_sum_of_subsequence_with_non_adjacent_elements/SolutionTest.java @@ -0,0 +1,23 @@ +package g3101_3200.s3165_maximum_sum_of_subsequence_with_non_adjacent_elements; + +import static org.hamcrest.CoreMatchers.equalTo; +import static org.hamcrest.MatcherAssert.assertThat; + +import org.junit.jupiter.api.Test; + +class SolutionTest { + @Test + void maximumSumSubsequence() { + assertThat( + new Solution() + .maximumSumSubsequence(new int[] {3, 5, 9}, new int[][] {{1, -2}, {0, -3}}), + equalTo(21)); + } + + @Test + void maximumSumSubsequence2() { + assertThat( + new Solution().maximumSumSubsequence(new int[] {0, -1}, new int[][] {{0, -5}}), + equalTo(0)); + } +}