From cd6caf88354fcfc0f1148a9c591254f5019e5fef Mon Sep 17 00:00:00 2001 From: Valentyn Kolesnikov Date: Sun, 31 Aug 2025 13:00:58 +0300 Subject: [PATCH 1/8] Added tasks 3663-3671 --- .../Solution.java | 29 +++++ .../readme.md | 33 ++++++ .../s3664_two_letter_card_game/Solution.java | 55 +++++++++ .../s3664_two_letter_card_game/readme.md | 58 +++++++++ .../Solution.java | 45 +++++++ .../s3665_twisted_mirror_path_count/readme.md | 75 ++++++++++++ .../Solution.java | 63 ++++++++++ .../readme.md | 51 ++++++++ .../Solution.java | 20 ++++ .../s3668_restore_finishing_order/readme.md | 38 ++++++ .../Solution.java | 74 ++++++++++++ .../readme.md | 38 ++++++ .../Solution.java | 62 ++++++++++ .../readme.md | 44 +++++++ .../Solution.java | 110 ++++++++++++++++++ .../readme.md | 72 ++++++++++++ .../SolutionTest.java | 18 +++ .../SolutionTest.java | 23 ++++ .../SolutionTest.java | 25 ++++ .../SolutionTest.java | 23 ++++ .../SolutionTest.java | 22 ++++ .../SolutionTest.java | 18 +++ .../SolutionTest.java | 23 ++++ .../SolutionTest.java | 18 +++ 24 files changed, 1037 insertions(+) create mode 100644 src/main/java/g3601_3700/s3663_find_the_least_frequent_digit/Solution.java create mode 100644 src/main/java/g3601_3700/s3663_find_the_least_frequent_digit/readme.md create mode 100644 src/main/java/g3601_3700/s3664_two_letter_card_game/Solution.java create mode 100644 src/main/java/g3601_3700/s3664_two_letter_card_game/readme.md create mode 100644 src/main/java/g3601_3700/s3665_twisted_mirror_path_count/Solution.java create mode 100644 src/main/java/g3601_3700/s3665_twisted_mirror_path_count/readme.md create mode 100644 src/main/java/g3601_3700/s3666_minimum_operations_to_equalize_binary_string/Solution.java create mode 100644 src/main/java/g3601_3700/s3666_minimum_operations_to_equalize_binary_string/readme.md create mode 100644 src/main/java/g3601_3700/s3668_restore_finishing_order/Solution.java create mode 100644 src/main/java/g3601_3700/s3668_restore_finishing_order/readme.md create mode 100644 src/main/java/g3601_3700/s3669_balanced_k_factor_decomposition/Solution.java create mode 100644 src/main/java/g3601_3700/s3669_balanced_k_factor_decomposition/readme.md create mode 100644 src/main/java/g3601_3700/s3670_maximum_product_of_two_integers_with_no_common_bits/Solution.java create mode 100644 src/main/java/g3601_3700/s3670_maximum_product_of_two_integers_with_no_common_bits/readme.md create mode 100644 src/main/java/g3601_3700/s3671_sum_of_beautiful_subsequences/Solution.java create mode 100644 src/main/java/g3601_3700/s3671_sum_of_beautiful_subsequences/readme.md create mode 100644 src/test/java/g3601_3700/s3663_find_the_least_frequent_digit/SolutionTest.java create mode 100644 src/test/java/g3601_3700/s3664_two_letter_card_game/SolutionTest.java create mode 100644 src/test/java/g3601_3700/s3665_twisted_mirror_path_count/SolutionTest.java create mode 100644 src/test/java/g3601_3700/s3666_minimum_operations_to_equalize_binary_string/SolutionTest.java create mode 100644 src/test/java/g3601_3700/s3668_restore_finishing_order/SolutionTest.java create mode 100644 src/test/java/g3601_3700/s3669_balanced_k_factor_decomposition/SolutionTest.java create mode 100644 src/test/java/g3601_3700/s3670_maximum_product_of_two_integers_with_no_common_bits/SolutionTest.java create mode 100644 src/test/java/g3601_3700/s3671_sum_of_beautiful_subsequences/SolutionTest.java diff --git a/src/main/java/g3601_3700/s3663_find_the_least_frequent_digit/Solution.java b/src/main/java/g3601_3700/s3663_find_the_least_frequent_digit/Solution.java new file mode 100644 index 000000000..7e89319c9 --- /dev/null +++ b/src/main/java/g3601_3700/s3663_find_the_least_frequent_digit/Solution.java @@ -0,0 +1,29 @@ +package g3601_3700.s3663_find_the_least_frequent_digit; + +// #Easy #Biweekly_Contest_164 #2025_08_31_Time_4_ms_(100.00%)_Space_41.21_MB_(100.00%) + +import java.util.HashMap; +import java.util.Map; + +public class Solution { + public int getLeastFrequentDigit(int n) { + String s = String.valueOf(n); + int k = s.length(); + Map freq = new HashMap<>(); + for (int i = 0; i < k; i++) { + int digit = s.charAt(i) - '0'; + freq.put(digit, freq.getOrDefault(digit, 0) + 1); + } + int minfreq = Integer.MAX_VALUE; + for (Map.Entry it : freq.entrySet()) { + minfreq = Math.min(minfreq, it.getValue()); + } + int result = 10; + for (Map.Entry it : freq.entrySet()) { + if (it.getValue() == minfreq) { + result = Math.min(result, it.getKey()); + } + } + return result; + } +} diff --git a/src/main/java/g3601_3700/s3663_find_the_least_frequent_digit/readme.md b/src/main/java/g3601_3700/s3663_find_the_least_frequent_digit/readme.md new file mode 100644 index 000000000..ed59979f0 --- /dev/null +++ b/src/main/java/g3601_3700/s3663_find_the_least_frequent_digit/readme.md @@ -0,0 +1,33 @@ +3663\. Find The Least Frequent Digit + +Easy + +Given an integer `n`, find the digit that occurs **least** frequently in its decimal representation. If multiple digits have the same frequency, choose the **smallest** digit. + +Return the chosen digit as an integer. + +The **frequency** of a digit `x` is the number of times it appears in the decimal representation of `n`. + +**Example 1:** + +**Input:** n = 1553322 + +**Output:** 1 + +**Explanation:** + +The least frequent digit in `n` is 1, which appears only once. All other digits appear twice. + +**Example 2:** + +**Input:** n = 723344511 + +**Output:** 2 + +**Explanation:** + +The least frequent digits in `n` are 7, 2, and 5; each appears only once. + +**Constraints:** + +* 1 <= n <= 231 - 1 \ No newline at end of file diff --git a/src/main/java/g3601_3700/s3664_two_letter_card_game/Solution.java b/src/main/java/g3601_3700/s3664_two_letter_card_game/Solution.java new file mode 100644 index 000000000..1c189f434 --- /dev/null +++ b/src/main/java/g3601_3700/s3664_two_letter_card_game/Solution.java @@ -0,0 +1,55 @@ +package g3601_3700.s3664_two_letter_card_game; + +// #Medium #Biweekly_Contest_164 #2025_08_31_Time_8_ms_(99.42%)_Space_60.09_MB_(52.34%) + +public class Solution { + public int score(String[] cards, char x) { + // store input midway as required + // counts for "x?" group by second char and "?x" group by first char + int[] left = new int[10]; + int[] right = new int[10]; + int xx = 0; + for (String c : cards) { + char a = c.charAt(0); + char b = c.charAt(1); + if (a == x && b == x) { + xx++; + } else if (a == x) { + left[b - 'a']++; + } else if (b == x) { + right[a - 'a']++; + } + } + // max pairs inside a group where pairs must come from different buckets: + // pairs = min(total/2, total - maxBucket) + int l = 0; + int maxL = 0; + for (int v : left) { + l += v; + if (v > maxL) { + maxL = v; + } + } + int r = 0; + int maxR = 0; + for (int v : right) { + r += v; + if (v > maxR) { + maxR = v; + } + } + int pairsLeft = Math.min(l / 2, l - maxL); + int pairsRight = Math.min(r / 2, r - maxR); + // leftovers after internal pairing + int leftoverL = l - 2 * pairsLeft; + int leftoverR = r - 2 * pairsRight; + int leftovers = leftoverL + leftoverR; + // First, use "xx" to pair with any leftovers + int useWithXX = Math.min(xx, leftovers); + int xxLeft = xx - useWithXX; + // If "xx" still remain, we can break existing internal pairs: + // breaking 1 internal pair frees 2 cards, which can pair with 2 "xx" to gain +1 net point + int extraByBreaking = Math.min(xxLeft / 2, pairsLeft + pairsRight); + return pairsLeft + pairsRight + useWithXX + extraByBreaking; + } +} diff --git a/src/main/java/g3601_3700/s3664_two_letter_card_game/readme.md b/src/main/java/g3601_3700/s3664_two_letter_card_game/readme.md new file mode 100644 index 000000000..fda7d8538 --- /dev/null +++ b/src/main/java/g3601_3700/s3664_two_letter_card_game/readme.md @@ -0,0 +1,58 @@ +3664\. Two-Letter Card Game + +Medium + +You are given a deck of cards represented by a string array `cards`, and each card displays two lowercase letters. + +You are also given a letter `x`. You play a game with the following rules: + +* Start with 0 points. +* On each turn, you must find two **compatible** cards from the deck that both contain the letter `x` in any position. +* Remove the pair of cards and earn **1 point**. +* The game ends when you can no longer find a pair of compatible cards. + +Return the **maximum** number of points you can gain with optimal play. + +Two cards are **compatible** if the strings differ in **exactly** 1 position. + +**Example 1:** + +**Input:** cards = ["aa","ab","ba","ac"], x = "a" + +**Output:** 2 + +**Explanation:** + +* On the first turn, select and remove cards `"ab"` and `"ac"`, which are compatible because they differ at only index 1. +* On the second turn, select and remove cards `"aa"` and `"ba"`, which are compatible because they differ at only index 0. + +Because there are no more compatible pairs, the total score is 2. + +**Example 2:** + +**Input:** cards = ["aa","ab","ba"], x = "a" + +**Output:** 1 + +**Explanation:** + +* On the first turn, select and remove cards `"aa"` and `"ba"`. + +Because there are no more compatible pairs, the total score is 1. + +**Example 3:** + +**Input:** cards = ["aa","ab","ba","ac"], x = "b" + +**Output:** 0 + +**Explanation:** + +The only cards that contain the character `'b'` are `"ab"` and `"ba"`. However, they differ in both indices, so they are not compatible. Thus, the output is 0. + +**Constraints:** + +* 2 <= cards.length <= 105 +* `cards[i].length == 2` +* Each `cards[i]` is composed of only lowercase English letters between `'a'` and `'j'`. +* `x` is a lowercase English letter between `'a'` and `'j'`. \ No newline at end of file diff --git a/src/main/java/g3601_3700/s3665_twisted_mirror_path_count/Solution.java b/src/main/java/g3601_3700/s3665_twisted_mirror_path_count/Solution.java new file mode 100644 index 000000000..32d9048c5 --- /dev/null +++ b/src/main/java/g3601_3700/s3665_twisted_mirror_path_count/Solution.java @@ -0,0 +1,45 @@ +package g3601_3700.s3665_twisted_mirror_path_count; + +// #Medium #Biweekly_Contest_164 #2025_08_31_Time_204_ms_(100.00%)_Space_86.33_MB_(100.00%) + +import java.util.Arrays; + +public class Solution { + private static final int MOD = 1000000007; + + public int uniquePaths(int[][] grid) { + int n = grid.length; + int m = grid[0].length; + int[][][] dp = new int[n][m][2]; + for (int i = 0; i < n; i++) { + for (int j = 0; j < m; j++) { + Arrays.fill(dp[i][j], -1); + } + } + return f(0, 0, 0, grid, n, m, dp); + } + + private int f(int i, int j, int dir, int[][] grid, int n, int m, int[][][] dp) { + if (i == n - 1 && j == m - 1) { + return 1; + } + if (i >= n || j >= m) { + return 0; + } + if (dp[i][j][dir] != -1) { + return dp[i][j][dir]; + } + long ways = 0; + if (grid[i][j] == 1) { + if (dir == 0) { + ways = f(i + 1, j, 1, grid, n, m, dp); + } else { + ways = f(i, j + 1, 0, grid, n, m, dp); + } + } else { + ways += f(i + 1, j, 1, grid, n, m, dp); + ways += f(i, j + 1, 0, grid, n, m, dp); + } + return dp[i][j][dir] = (int) ways % MOD; + } +} diff --git a/src/main/java/g3601_3700/s3665_twisted_mirror_path_count/readme.md b/src/main/java/g3601_3700/s3665_twisted_mirror_path_count/readme.md new file mode 100644 index 000000000..62bec19ac --- /dev/null +++ b/src/main/java/g3601_3700/s3665_twisted_mirror_path_count/readme.md @@ -0,0 +1,75 @@ +3665\. Twisted Mirror Path Count + +Medium + +Given an `m x n` binary grid `grid` where: + +* `grid[i][j] == 0` represents an empty cell, and +* `grid[i][j] == 1` represents a mirror. + +A robot starts at the top-left corner of the grid `(0, 0)` and wants to reach the bottom-right corner `(m - 1, n - 1)`. It can move only **right** or **down**. If the robot attempts to move into a mirror cell, it is **reflected** before entering that cell: + +* If it tries to move **right** into a mirror, it is turned **down** and moved into the cell directly below the mirror. +* If it tries to move **down** into a mirror, it is turned **right** and moved into the cell directly to the right of the mirror. + +If this reflection would cause the robot to move outside the `grid` boundaries, the path is considered invalid and should not be counted. + +Return the number of unique valid paths from `(0, 0)` to `(m - 1, n - 1)`. + +Since the answer may be very large, return it **modulo** 109 + 7. + +**Note**: If a reflection moves the robot into a mirror cell, the robot is immediately reflected again based on the direction it used to enter that mirror: if it entered while moving right, it will be turned down; if it entered while moving down, it will be turned right. This process will continue until either the last cell is reached, the robot moves out of bounds or the robot moves to a non-mirror cell. + +**Example 1:** + +**Input:** grid = [[0,1,0],[0,0,1],[1,0,0]] + +**Output:** 5 + +**Explanation:** + +| Number | Full Path | +|--------|---------------------------------------------------------------------| +| 1 | (0, 0) → (0, 1) [M] → (1, 1) → (1, 2) [M] → (2, 2) | +| 2 | (0, 0) → (0, 1) [M] → (1, 1) → (2, 1) → (2, 2) | +| 3 | (0, 0) → (1, 0) → (1, 1) → (1, 2) [M] → (2, 2) | +| 4 | (0, 0) → (1, 0) → (1, 1) → (2, 1) → (2, 2) | +| 5 | (0, 0) → (1, 0) → (2, 0) [M] → (2, 1) → (2, 2) | + +* `[M]` indicates the robot attempted to enter a mirror cell and instead reflected. + + +**Example 2:** + +**Input:** grid = [[0,0],[0,0]] + +**Output:** 2 + +**Explanation:** + +| Number | Full Path | +|--------|-----------------------------| +| 1 | (0, 0) → (0, 1) → (1, 1) | +| 2 | (0, 0) → (1, 0) → (1, 1) | + +**Example 3:** + +**Input:** grid = [[0,1,1],[1,1,0]] + +**Output:** 1 + +**Explanation:** + +| Number | Full Path | +|--------|-------------------------------------------| +| 1 | (0, 0) → (0, 1) [M] → (1, 1) [M] → (1, 2) | + +`(0, 0) → (1, 0) [M] → (1, 1) [M] → (2, 1)` goes out of bounds, so it is invalid. + +**Constraints:** + +* `m == grid.length` +* `n == grid[i].length` +* `2 <= m, n <= 500` +* `grid[i][j]` is either `0` or `1`. +* `grid[0][0] == grid[m - 1][n - 1] == 0` \ No newline at end of file diff --git a/src/main/java/g3601_3700/s3666_minimum_operations_to_equalize_binary_string/Solution.java b/src/main/java/g3601_3700/s3666_minimum_operations_to_equalize_binary_string/Solution.java new file mode 100644 index 000000000..eebfb79a3 --- /dev/null +++ b/src/main/java/g3601_3700/s3666_minimum_operations_to_equalize_binary_string/Solution.java @@ -0,0 +1,63 @@ +package g3601_3700.s3666_minimum_operations_to_equalize_binary_string; + +// #Hard #Biweekly_Contest_164 #2025_08_31_Time_22_ms_(100.00%)_Space_45.62_MB_(100.00%) + +import java.util.ArrayDeque; +import java.util.Queue; + +public class Solution { + public int minOperations(String s, int k) { + int zeros = s.chars().map(x -> x == '0' ? 1 : 0).sum(); + if ((zeros % k) == 0) { + return zeros / k; + } + int n = s.length(); + Queue q = new ArrayDeque<>(); + q.add(zeros); + int res = 1; + // use bounds for optimization + int[][] bounds = new int[2][2]; + bounds[zeros & 1][0] = bounds[zeros & 1][1] = zeros; + bounds[1 - (zeros & 1)][0] = Integer.MAX_VALUE; + bounds[1 - (zeros & 1)][1] = Integer.MIN_VALUE; + while (!q.isEmpty()) { + // find min number of zeros and max number of zeros in this round + int minv = Integer.MAX_VALUE; + int maxv = Integer.MIN_VALUE; + for (int len = q.size(); len > 0; len--) { + int h = q.poll(); + int t = n - h; + int x = Math.min(h, k); + if (t >= k - x) { + int fst = h - x + (k - x); + minv = Math.min(minv, fst); + maxv = Math.max(maxv, fst); + } + x = Math.min(t, k); + if (h >= k - x) { + int snd = h - (k - x) + x; + minv = Math.min(minv, snd); + maxv = Math.max(maxv, snd); + } + } + // possible children are sequence of equal difference 2 + int ind = minv & 1; + int temp = minv; + while (temp <= maxv) { + if ((temp % k) == 0) { + return res + temp / k; + } + if (temp < bounds[ind][0] || temp > bounds[ind][1]) { + q.add(temp); + temp += 2; + } else { + temp = bounds[ind][1] + 2; + } + } + bounds[ind][0] = Math.min(bounds[ind][0], minv); + bounds[ind][1] = Math.max(bounds[ind][1], maxv); + res++; + } + return -1; + } +} diff --git a/src/main/java/g3601_3700/s3666_minimum_operations_to_equalize_binary_string/readme.md b/src/main/java/g3601_3700/s3666_minimum_operations_to_equalize_binary_string/readme.md new file mode 100644 index 000000000..cc5ab4bcd --- /dev/null +++ b/src/main/java/g3601_3700/s3666_minimum_operations_to_equalize_binary_string/readme.md @@ -0,0 +1,51 @@ +3666\. Minimum Operations to Equalize Binary String + +Hard + +You are given a binary string `s`, and an integer `k`. + +In one operation, you must choose **exactly** `k` **different** indices and **flip** each `'0'` to `'1'` and each `'1'` to `'0'`. + +Return the **minimum** number of operations required to make all characters in the string equal to `'1'`. If it is not possible, return -1. + +**Example 1:** + +**Input:** s = "110", k = 1 + +**Output:** 1 + +**Explanation:** + +* There is one `'0'` in `s`. +* Since `k = 1`, we can flip it directly in one operation. + +**Example 2:** + +**Input:** s = "0101", k = 3 + +**Output:** 2 + +**Explanation:** + +One optimal set of operations choosing `k = 3` indices in each operation is: + +* **Operation 1**: Flip indices `[0, 1, 3]`. `s` changes from `"0101"` to `"1000"`. +* **Operation 2**: Flip indices `[1, 2, 3]`. `s` changes from `"1000"` to `"1111"`. + +Thus, the minimum number of operations is 2. + +**Example 3:** + +**Input:** s = "101", k = 2 + +**Output:** \-1 + +**Explanation:** + +Since `k = 2` and `s` has only one `'0'`, it is impossible to flip exactly `k` indices to make all `'1'`. Hence, the answer is -1. + +**Constraints:** + +* 1 <= s.length <= 105 +* `s[i]` is either `'0'` or `'1'`. +* `1 <= k <= s.length` \ No newline at end of file diff --git a/src/main/java/g3601_3700/s3668_restore_finishing_order/Solution.java b/src/main/java/g3601_3700/s3668_restore_finishing_order/Solution.java new file mode 100644 index 000000000..a4a707119 --- /dev/null +++ b/src/main/java/g3601_3700/s3668_restore_finishing_order/Solution.java @@ -0,0 +1,20 @@ +package g3601_3700.s3668_restore_finishing_order; + +// #Easy #Weekly_Contest_465 #2025_08_31_Time_1_ms_(100.00%)_Space_45.15_MB_(49.19%) + +public class Solution { + public int[] recoverOrder(int[] order, int[] friends) { + int[] rs = new int[friends.length]; + int index = 0; + for (int k : order) { + for (int friend : friends) { + if (k == friend) { + rs[index] = k; + index++; + break; + } + } + } + return rs; + } +} diff --git a/src/main/java/g3601_3700/s3668_restore_finishing_order/readme.md b/src/main/java/g3601_3700/s3668_restore_finishing_order/readme.md new file mode 100644 index 000000000..04a121df1 --- /dev/null +++ b/src/main/java/g3601_3700/s3668_restore_finishing_order/readme.md @@ -0,0 +1,38 @@ +3668\. Restore Finishing Order + +Easy + +You are given an integer array `order` of length `n` and an integer array `friends`. + +* `order` contains every integer from 1 to `n` **exactly once**, representing the IDs of the participants of a race in their **finishing** order. +* `friends` contains the IDs of your friends in the race **sorted** in strictly increasing order. Each ID in friends is guaranteed to appear in the `order` array. + +Return an array containing your friends' IDs in their **finishing** order. + +**Example 1:** + +**Input:** order = [3,1,2,5,4], friends = [1,3,4] + +**Output:** [3,1,4] + +**Explanation:** + +The finishing order is [**3**, **1**, 2, 5, **4**]. Therefore, the finishing order of your friends is `[3, 1, 4]`. + +**Example 2:** + +**Input:** order = [1,4,5,3,2], friends = [2,5] + +**Output:** [5,2] + +**Explanation:** + +The finishing order is [1, 4, **5**, 3, **2**]. Therefore, the finishing order of your friends is `[5, 2]`. + +**Constraints:** + +* `1 <= n == order.length <= 100` +* `order` contains every integer from 1 to `n` exactly once +* `1 <= friends.length <= min(8, n)` +* `1 <= friends[i] <= n` +* `friends` is strictly increasing \ No newline at end of file diff --git a/src/main/java/g3601_3700/s3669_balanced_k_factor_decomposition/Solution.java b/src/main/java/g3601_3700/s3669_balanced_k_factor_decomposition/Solution.java new file mode 100644 index 000000000..92817a003 --- /dev/null +++ b/src/main/java/g3601_3700/s3669_balanced_k_factor_decomposition/Solution.java @@ -0,0 +1,74 @@ +package g3601_3700.s3669_balanced_k_factor_decomposition; + +// #Medium #Weekly_Contest_465 #2025_08_31_Time_13_ms_(73.81%)_Space_45.35_MB_(27.49%) + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +public class Solution { + private int kGlobal; + private int bestDiff = Integer.MAX_VALUE; + private List bestList = new ArrayList<>(); + private final List current = new ArrayList<>(); + + public int[] minDifference(int n, int k) { + kGlobal = k; + dfs(n, 1, 0); + int[] ans = new int[bestList.size()]; + for (int i = 0; i < bestList.size(); i++) { + ans[i] = bestList.get(i); + } + return ans; + } + + private void dfs(int rem, int start, int depth) { + if (depth == kGlobal - 1) { + if (rem >= start) { + current.add(rem); + evaluate(); + current.remove(current.size() - 1); + } + return; + } + List divs = getDivisors(rem); + for (int d : divs) { + if (d < start) { + continue; + } + current.add(d); + dfs(rem / d, d, depth + 1); + current.remove(current.size() - 1); + } + } + + private void evaluate() { + int mn = Integer.MAX_VALUE; + int mx = Integer.MIN_VALUE; + for (int v : current) { + mn = Math.min(mn, v); + mx = Math.max(mx, v); + } + int diff = mx - mn; + if (diff < bestDiff) { + bestDiff = diff; + bestList = new ArrayList<>(current); + } + } + + private List getDivisors(int x) { + List small = new ArrayList<>(); + List large = new ArrayList<>(); + for (int i = 1; i * (long) i <= x; i++) { + if (x % i == 0) { + small.add(i); + if (i != x / i) { + large.add(x / i); + } + } + } + Collections.reverse(large); + small.addAll(large); + return small; + } +} diff --git a/src/main/java/g3601_3700/s3669_balanced_k_factor_decomposition/readme.md b/src/main/java/g3601_3700/s3669_balanced_k_factor_decomposition/readme.md new file mode 100644 index 000000000..8123c6df6 --- /dev/null +++ b/src/main/java/g3601_3700/s3669_balanced_k_factor_decomposition/readme.md @@ -0,0 +1,38 @@ +3669\. Balanced K-Factor Decomposition + +Medium + +Given two integers `n` and `k`, split the number `n` into exactly `k` positive integers such that the **product** of these integers is equal to `n`. + +Return _any_ _one_ split in which the **maximum** difference between any two numbers is **minimized**. You may return the result in _any order_. + +**Example 1:** + +**Input:** n = 100, k = 2 + +**Output:** [10,10] + +**Explanation:** + +The split `[10, 10]` yields `10 * 10 = 100` and a max-min difference of 0, which is minimal. + +**Example 2:** + +**Input:** n = 44, k = 3 + +**Output:** [2,2,11] + +**Explanation:** + +* Split `[1, 1, 44]` yields a difference of 43 +* Split `[1, 2, 22]` yields a difference of 21 +* Split `[1, 4, 11]` yields a difference of 10 +* Split `[2, 2, 11]` yields a difference of 9 + +Therefore, `[2, 2, 11]` is the optimal split with the smallest difference 9. + +**Constraints:** + +* 4 <= n <= 105 +* `2 <= k <= 5` +* `k` is strictly less than the total number of positive divisors of `n`. \ No newline at end of file diff --git a/src/main/java/g3601_3700/s3670_maximum_product_of_two_integers_with_no_common_bits/Solution.java b/src/main/java/g3601_3700/s3670_maximum_product_of_two_integers_with_no_common_bits/Solution.java new file mode 100644 index 000000000..9b9a1315c --- /dev/null +++ b/src/main/java/g3601_3700/s3670_maximum_product_of_two_integers_with_no_common_bits/Solution.java @@ -0,0 +1,62 @@ +package g3601_3700.s3670_maximum_product_of_two_integers_with_no_common_bits; + +// #Medium #Weekly_Contest_465 #2025_08_31_Time_138_ms_(99.69%)_Space_64.47_MB_(29.81%) + +public class Solution { + public long maxProduct(int[] nums) { + // Find highest value to limit DP size + int maxVal = 0; + for (int v : nums) { + if (v > maxVal) { + maxVal = v; + } + } + // If all numbers are >=1, maxVal > 0; compute needed bit-width + // in [1..20] + int maxBits = 32 - Integer.numberOfLeadingZeros(maxVal); + int size = 1 << maxBits; + // ---- store input midway, as required ---- + // dp[mask] = largest number present whose bitmask == mask (later becomes: max over all + // submasks) + int[] dp = new int[size]; + for (int x : nums) { + // numbers themselves are their masks + if (dp[x] < x) { + dp[x] = x; + } + } + // SOS DP: for each bit b, propagate lower-half block maxima to upper-half block + // (branch-light) + for (int b = 0; b < maxBits; b++) { + int half = 1 << b; + int step = half << 1; + for (int base = 0; base < size; base += step) { + int upper = base + half; + for (int m = 0; m < half; m++) { + int u = upper + m; + int l = base + m; + if (dp[u] < dp[l]) { + dp[u] = dp[l]; + } + } + } + } + // Now dp[mask] = max value among all submasks of 'mask' + long ans = 0; + int full = size - 1; + for (int x : nums) { + // masks with no bits in common with x + int complement = (~x) & full; + // best partner disjoint with x + int y = dp[complement]; + if (y > 0) { + long prod = (long) x * y; + if (prod > ans) { + ans = prod; + } + } + } + // 0 if no valid pair + return ans; + } +} diff --git a/src/main/java/g3601_3700/s3670_maximum_product_of_two_integers_with_no_common_bits/readme.md b/src/main/java/g3601_3700/s3670_maximum_product_of_two_integers_with_no_common_bits/readme.md new file mode 100644 index 000000000..4caebe981 --- /dev/null +++ b/src/main/java/g3601_3700/s3670_maximum_product_of_two_integers_with_no_common_bits/readme.md @@ -0,0 +1,44 @@ +3670\. Maximum Product of Two Integers With No Common Bits + +Medium + +You are given an integer array `nums`. + +Your task is to find two **distinct** indices `i` and `j` such that the product `nums[i] * nums[j]` is **maximized,** and the binary representations of `nums[i]` and `nums[j]` do not share any common set bits. + +Return the **maximum** possible product of such a pair. If no such pair exists, return 0. + +**Example 1:** + +**Input:** nums = [1,2,3,4,5,6,7] + +**Output:** 12 + +**Explanation:** + +The best pair is 3 (011) and 4 (100). They share no set bits and `3 * 4 = 12`. + +**Example 2:** + +**Input:** nums = [5,6,4] + +**Output:** 0 + +**Explanation:** + +Every pair of numbers has at least one common set bit. Hence, the answer is 0. + +**Example 3:** + +**Input:** nums = [64,8,32] + +**Output:** 2048 + +**Explanation:** + +No pair of numbers share a common bit, so the answer is the product of the two maximum elements, 64 and 32 (`64 * 32 = 2048`). + +**Constraints:** + +* 2 <= nums.length <= 105 +* 1 <= nums[i] <= 106 \ No newline at end of file diff --git a/src/main/java/g3601_3700/s3671_sum_of_beautiful_subsequences/Solution.java b/src/main/java/g3601_3700/s3671_sum_of_beautiful_subsequences/Solution.java new file mode 100644 index 000000000..d847b9e5a --- /dev/null +++ b/src/main/java/g3601_3700/s3671_sum_of_beautiful_subsequences/Solution.java @@ -0,0 +1,110 @@ +package g3601_3700.s3671_sum_of_beautiful_subsequences; + +// #Hard #Weekly_Contest_465 #2025_08_31_Time_224_ms_(99.03%)_Space_56.07_MB_(89.32%) + +public class Solution { + private static final int MOD = 1000000007; + + public int totalBeauty(int[] nums) { + int maxV = 0; + for (int v : nums) { + if (v > maxV) { + maxV = v; + } + } + // index by g + Fenwick[] fenwicks = new Fenwick[maxV + 1]; + // FDiv[g] = # inc subseq with all elements multiple of g + long[] fDiv = new long[maxV + 1]; + // temp buffer for divisors (max divisors of any number <= ~128 for this constraint) + int[] divisors = new int[256]; + // Left-to-right DP restricted to multiples of each divisor g + for (int x : nums) { + int cnt = 0; + int r = (int) Math.sqrt(x); + for (int d = 1; d <= r; d++) { + if (x % d == 0) { + divisors[cnt++] = d; + int d2 = x / d; + if (d2 != d) { + divisors[cnt++] = d2; + } + } + } + for (int i = 0; i < cnt; i++) { + int g = divisors[i]; + // coordinate in [1..maxV/g] for this g + int idxQ = x / g; + Fenwick fw = fenwicks[g]; + if (fw == null) { + // size needs to be >= max index (maxV/g). Use +2 for safety and 1-based + // indexing. + fw = new Fenwick(maxV / g + 2); + fenwicks[g] = fw; + } + long dp = 1 + fw.query(idxQ - 1); + if (dp >= MOD) { + dp -= MOD; + } + fw.add(idxQ, dp); + fDiv[g] += dp; + if (fDiv[g] >= MOD) { + fDiv[g] -= MOD; + } + } + } + + // Inclusion–exclusion to get exact gcd counts + long[] exact = new long[maxV + 1]; + for (int g = maxV; g >= 1; g--) { + long s = fDiv[g]; + for (int m = g + g; m <= maxV; m += g) { + s -= exact[m]; + if (s < 0) { + s += MOD; + } + } + exact[g] = s; + } + + long ans = 0; + for (int g = 1; g <= maxV; g++) { + if (exact[g] != 0) { + ans += exact[g] * g % MOD; + if (ans >= MOD) { + ans -= MOD; + } + } + } + return (int) ans; + } + + private static final class Fenwick { + private final long[] tree; + + Fenwick(int size) { + this.tree = new long[size]; + } + + void add(int indexOneBased, long delta) { + for (int i = indexOneBased; i < tree.length; i += i & -i) { + long v = tree[i] + delta; + if (v >= MOD) { + v -= MOD; + } + tree[i] = v; + } + } + + long query(int indexOneBased) { + long sum = 0; + for (int i = indexOneBased; i > 0; i -= i & -i) { + sum += tree[i]; + if (sum >= MOD) { + sum -= MOD; + } + } + return sum; + } + } +} diff --git a/src/main/java/g3601_3700/s3671_sum_of_beautiful_subsequences/readme.md b/src/main/java/g3601_3700/s3671_sum_of_beautiful_subsequences/readme.md new file mode 100644 index 000000000..8655b9d7b --- /dev/null +++ b/src/main/java/g3601_3700/s3671_sum_of_beautiful_subsequences/readme.md @@ -0,0 +1,72 @@ +3671\. Sum of Beautiful Subsequences + +Hard + +You are given an integer array `nums` of length `n`. + +For every **positive** integer `g`, we define the **beauty** of `g` as the **product** of `g` and the number of **strictly increasing** **subsequences** of `nums` whose greatest common divisor (GCD) is exactly `g`. + +Return the **sum** of **beauty** values for all positive integers `g`. + +Since the answer could be very large, return it modulo 109 + 7. + +**Example 1:** + +**Input:** nums = [1,2,3] + +**Output:** 10 + +**Explanation:** + +All strictly increasing subsequences and their GCDs are: + +| Subsequence | GCD | +|-------------|-----| +| [1] | 1 | +| [2] | 2 | +| [3] | 3 | +| [1,2] | 1 | +| [1,3] | 1 | +| [2,3] | 1 | +| [1,2,3] | 1 | + +Calculating beauty for each GCD: + +| GCD | Count of subsequences | Beauty (GCD × Count) | +|-----|------------------------|----------------------| +| 1 | 5 | 1 × 5 = 5 | +| 2 | 1 | 2 × 1 = 2 | +| 3 | 1 | 3 × 1 = 3 | + +Total beauty is `5 + 2 + 3 = 10`. + +**Example 2:** + +**Input:** nums = [4,6] + +**Output:** 12 + +**Explanation:** + +All strictly increasing subsequences and their GCDs are: + +| Subsequence | GCD | +|-------------|-----| +| [4] | 4 | +| [6] | 6 | +| [4,6] | 2 | + +Calculating beauty for each GCD: + +| GCD | Count of subsequences | Beauty (GCD × Count) | +|-----|------------------------|----------------------| +| 2 | 1 | 2 × 1 = 2 | +| 4 | 1 | 4 × 1 = 4 | +| 6 | 1 | 6 × 1 = 6 | + +Total beauty is `2 + 4 + 6 = 12`. + +**Constraints:** + +* 1 <= n == nums.length <= 104 +* 1 <= nums[i] <= 7 * 104 \ No newline at end of file diff --git a/src/test/java/g3601_3700/s3663_find_the_least_frequent_digit/SolutionTest.java b/src/test/java/g3601_3700/s3663_find_the_least_frequent_digit/SolutionTest.java new file mode 100644 index 000000000..c98a086bf --- /dev/null +++ b/src/test/java/g3601_3700/s3663_find_the_least_frequent_digit/SolutionTest.java @@ -0,0 +1,18 @@ +package g3601_3700.s3663_find_the_least_frequent_digit; + +import static org.hamcrest.CoreMatchers.equalTo; +import static org.hamcrest.MatcherAssert.assertThat; + +import org.junit.jupiter.api.Test; + +class SolutionTest { + @Test + void getLeastFrequentDigit() { + assertThat(new Solution().getLeastFrequentDigit(1553322), equalTo(1)); + } + + @Test + void getLeastFrequentDigit2() { + assertThat(new Solution().getLeastFrequentDigit(723344511), equalTo(2)); + } +} diff --git a/src/test/java/g3601_3700/s3664_two_letter_card_game/SolutionTest.java b/src/test/java/g3601_3700/s3664_two_letter_card_game/SolutionTest.java new file mode 100644 index 000000000..fd250d918 --- /dev/null +++ b/src/test/java/g3601_3700/s3664_two_letter_card_game/SolutionTest.java @@ -0,0 +1,23 @@ +package g3601_3700.s3664_two_letter_card_game; + +import static org.hamcrest.CoreMatchers.equalTo; +import static org.hamcrest.MatcherAssert.assertThat; + +import org.junit.jupiter.api.Test; + +class SolutionTest { + @Test + void score() { + assertThat(new Solution().score(new String[] {"aa", "ab", "ba", "ac"}, 'a'), equalTo(2)); + } + + @Test + void score2() { + assertThat(new Solution().score(new String[] {"aa", "ab", "ba"}, 'a'), equalTo(1)); + } + + @Test + void score3() { + assertThat(new Solution().score(new String[] {"aa", "ab", "ba", "ac"}, 'b'), equalTo(0)); + } +} diff --git a/src/test/java/g3601_3700/s3665_twisted_mirror_path_count/SolutionTest.java b/src/test/java/g3601_3700/s3665_twisted_mirror_path_count/SolutionTest.java new file mode 100644 index 000000000..fec49901b --- /dev/null +++ b/src/test/java/g3601_3700/s3665_twisted_mirror_path_count/SolutionTest.java @@ -0,0 +1,25 @@ +package g3601_3700.s3665_twisted_mirror_path_count; + +import static org.hamcrest.CoreMatchers.equalTo; +import static org.hamcrest.MatcherAssert.assertThat; + +import org.junit.jupiter.api.Test; + +class SolutionTest { + @Test + void uniquePaths() { + assertThat( + new Solution().uniquePaths(new int[][] {{0, 1, 0}, {0, 0, 1}, {1, 0, 0}}), + equalTo(5)); + } + + @Test + void uniquePaths2() { + assertThat(new Solution().uniquePaths(new int[][] {{0, 0}, {0, 0}}), equalTo(2)); + } + + @Test + void uniquePaths3() { + assertThat(new Solution().uniquePaths(new int[][] {{0, 1, 1}, {1, 1, 0}}), equalTo(1)); + } +} diff --git a/src/test/java/g3601_3700/s3666_minimum_operations_to_equalize_binary_string/SolutionTest.java b/src/test/java/g3601_3700/s3666_minimum_operations_to_equalize_binary_string/SolutionTest.java new file mode 100644 index 000000000..acab41602 --- /dev/null +++ b/src/test/java/g3601_3700/s3666_minimum_operations_to_equalize_binary_string/SolutionTest.java @@ -0,0 +1,23 @@ +package g3601_3700.s3666_minimum_operations_to_equalize_binary_string; + +import static org.hamcrest.CoreMatchers.equalTo; +import static org.hamcrest.MatcherAssert.assertThat; + +import org.junit.jupiter.api.Test; + +class SolutionTest { + @Test + void minOperations() { + assertThat(new Solution().minOperations("110", 1), equalTo(1)); + } + + @Test + void minOperations2() { + assertThat(new Solution().minOperations("0101", 3), equalTo(2)); + } + + @Test + void minOperations3() { + assertThat(new Solution().minOperations("101", 2), equalTo(-1)); + } +} diff --git a/src/test/java/g3601_3700/s3668_restore_finishing_order/SolutionTest.java b/src/test/java/g3601_3700/s3668_restore_finishing_order/SolutionTest.java new file mode 100644 index 000000000..5ef548ddb --- /dev/null +++ b/src/test/java/g3601_3700/s3668_restore_finishing_order/SolutionTest.java @@ -0,0 +1,22 @@ +package g3601_3700.s3668_restore_finishing_order; + +import static org.hamcrest.CoreMatchers.equalTo; +import static org.hamcrest.MatcherAssert.assertThat; + +import org.junit.jupiter.api.Test; + +class SolutionTest { + @Test + void recoverOrder() { + assertThat( + new Solution().recoverOrder(new int[] {3, 1, 2, 5, 4}, new int[] {1, 3, 4}), + equalTo(new int[] {3, 1, 4})); + } + + @Test + void recoverOrder2() { + assertThat( + new Solution().recoverOrder(new int[] {1, 4, 5, 3, 2}, new int[] {2, 5}), + equalTo(new int[] {5, 2})); + } +} diff --git a/src/test/java/g3601_3700/s3669_balanced_k_factor_decomposition/SolutionTest.java b/src/test/java/g3601_3700/s3669_balanced_k_factor_decomposition/SolutionTest.java new file mode 100644 index 000000000..47474f074 --- /dev/null +++ b/src/test/java/g3601_3700/s3669_balanced_k_factor_decomposition/SolutionTest.java @@ -0,0 +1,18 @@ +package g3601_3700.s3669_balanced_k_factor_decomposition; + +import static org.hamcrest.CoreMatchers.equalTo; +import static org.hamcrest.MatcherAssert.assertThat; + +import org.junit.jupiter.api.Test; + +class SolutionTest { + @Test + void minDifference() { + assertThat(new Solution().minDifference(100, 2), equalTo(new int[] {10, 10})); + } + + @Test + void minDifference2() { + assertThat(new Solution().minDifference(44, 3), equalTo(new int[] {2, 2, 11})); + } +} diff --git a/src/test/java/g3601_3700/s3670_maximum_product_of_two_integers_with_no_common_bits/SolutionTest.java b/src/test/java/g3601_3700/s3670_maximum_product_of_two_integers_with_no_common_bits/SolutionTest.java new file mode 100644 index 000000000..68e9354dc --- /dev/null +++ b/src/test/java/g3601_3700/s3670_maximum_product_of_two_integers_with_no_common_bits/SolutionTest.java @@ -0,0 +1,23 @@ +package g3601_3700.s3670_maximum_product_of_two_integers_with_no_common_bits; + +import static org.hamcrest.CoreMatchers.equalTo; +import static org.hamcrest.MatcherAssert.assertThat; + +import org.junit.jupiter.api.Test; + +class SolutionTest { + @Test + void maxProduct() { + assertThat(new Solution().maxProduct(new int[] {1, 2, 3, 4, 5, 6, 7}), equalTo(12L)); + } + + @Test + void maxProduct2() { + assertThat(new Solution().maxProduct(new int[] {4, 5, 6}), equalTo(0L)); + } + + @Test + void maxProduct3() { + assertThat(new Solution().maxProduct(new int[] {64, 8, 32}), equalTo(2048L)); + } +} diff --git a/src/test/java/g3601_3700/s3671_sum_of_beautiful_subsequences/SolutionTest.java b/src/test/java/g3601_3700/s3671_sum_of_beautiful_subsequences/SolutionTest.java new file mode 100644 index 000000000..9ca8fec7b --- /dev/null +++ b/src/test/java/g3601_3700/s3671_sum_of_beautiful_subsequences/SolutionTest.java @@ -0,0 +1,18 @@ +package g3601_3700.s3671_sum_of_beautiful_subsequences; + +import static org.hamcrest.CoreMatchers.equalTo; +import static org.hamcrest.MatcherAssert.assertThat; + +import org.junit.jupiter.api.Test; + +class SolutionTest { + @Test + void totalBeauty() { + assertThat(new Solution().totalBeauty(new int[] {1, 2, 3}), equalTo(10)); + } + + @Test + void totalBeauty2() { + assertThat(new Solution().totalBeauty(new int[] {4, 6}), equalTo(12)); + } +} From 441dcfdb7bc4bde0878dda0afead862444b12083 Mon Sep 17 00:00:00 2001 From: Valentyn Kolesnikov Date: Sun, 31 Aug 2025 13:03:05 +0300 Subject: [PATCH 2/8] Fixed format --- .../s3671_sum_of_beautiful_subsequences/Solution.java | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/main/java/g3601_3700/s3671_sum_of_beautiful_subsequences/Solution.java b/src/main/java/g3601_3700/s3671_sum_of_beautiful_subsequences/Solution.java index d847b9e5a..0862fb50d 100644 --- a/src/main/java/g3601_3700/s3671_sum_of_beautiful_subsequences/Solution.java +++ b/src/main/java/g3601_3700/s3671_sum_of_beautiful_subsequences/Solution.java @@ -53,7 +53,6 @@ public int totalBeauty(int[] nums) { } } } - // Inclusion–exclusion to get exact gcd counts long[] exact = new long[maxV + 1]; for (int g = maxV; g >= 1; g--) { @@ -66,7 +65,6 @@ public int totalBeauty(int[] nums) { } exact[g] = s; } - long ans = 0; for (int g = 1; g <= maxV; g++) { if (exact[g] != 0) { @@ -81,7 +79,6 @@ public int totalBeauty(int[] nums) { private static final class Fenwick { private final long[] tree; - Fenwick(int size) { this.tree = new long[size]; } From 663237416c3bd1aabf022b6e2652cb63ef8d105d Mon Sep 17 00:00:00 2001 From: Valentyn Kolesnikov Date: Sun, 31 Aug 2025 13:11:32 +0300 Subject: [PATCH 3/8] Fixed format --- .../g3601_3700/s3665_twisted_mirror_path_count/Solution.java | 3 ++- .../s3671_sum_of_beautiful_subsequences/Solution.java | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/main/java/g3601_3700/s3665_twisted_mirror_path_count/Solution.java b/src/main/java/g3601_3700/s3665_twisted_mirror_path_count/Solution.java index 32d9048c5..1803645cb 100644 --- a/src/main/java/g3601_3700/s3665_twisted_mirror_path_count/Solution.java +++ b/src/main/java/g3601_3700/s3665_twisted_mirror_path_count/Solution.java @@ -40,6 +40,7 @@ private int f(int i, int j, int dir, int[][] grid, int n, int m, int[][][] dp) { ways += f(i + 1, j, 1, grid, n, m, dp); ways += f(i, j + 1, 0, grid, n, m, dp); } - return dp[i][j][dir] = (int) ways % MOD; + dp[i][j][dir] = (int) ways % MOD; + return dp[i][j][dir]; } } diff --git a/src/main/java/g3601_3700/s3671_sum_of_beautiful_subsequences/Solution.java b/src/main/java/g3601_3700/s3671_sum_of_beautiful_subsequences/Solution.java index 0862fb50d..6aa7d9708 100644 --- a/src/main/java/g3601_3700/s3671_sum_of_beautiful_subsequences/Solution.java +++ b/src/main/java/g3601_3700/s3671_sum_of_beautiful_subsequences/Solution.java @@ -79,6 +79,7 @@ public int totalBeauty(int[] nums) { private static final class Fenwick { private final long[] tree; + Fenwick(int size) { this.tree = new long[size]; } From f0426e574251f5422f18a395dd67391af4c304e7 Mon Sep 17 00:00:00 2001 From: Valentyn Kolesnikov Date: Sat, 6 Sep 2025 13:20:57 +0300 Subject: [PATCH 4/8] Updated tags --- .../Solution.java | 34 ++-- .../s3664_two_letter_card_game/Solution.java | 2 +- .../Solution.java | 57 +++---- .../Solution.java | 147 +++++++++++------- .../Solution.java | 2 +- .../Solution.java | 2 +- .../Solution.java | 2 +- .../Solution.java | 2 +- 8 files changed, 140 insertions(+), 108 deletions(-) diff --git a/src/main/java/g3601_3700/s3663_find_the_least_frequent_digit/Solution.java b/src/main/java/g3601_3700/s3663_find_the_least_frequent_digit/Solution.java index 7e89319c9..e39e24fe1 100644 --- a/src/main/java/g3601_3700/s3663_find_the_least_frequent_digit/Solution.java +++ b/src/main/java/g3601_3700/s3663_find_the_least_frequent_digit/Solution.java @@ -1,27 +1,25 @@ package g3601_3700.s3663_find_the_least_frequent_digit; -// #Easy #Biweekly_Contest_164 #2025_08_31_Time_4_ms_(100.00%)_Space_41.21_MB_(100.00%) - -import java.util.HashMap; -import java.util.Map; +// #Easy #Biweekly_Contest_164 #2025_09_06_Time_1_ms_(97.91%)_Space_41.14_MB_(60.27%) public class Solution { public int getLeastFrequentDigit(int n) { - String s = String.valueOf(n); - int k = s.length(); - Map freq = new HashMap<>(); - for (int i = 0; i < k; i++) { - int digit = s.charAt(i) - '0'; - freq.put(digit, freq.getOrDefault(digit, 0) + 1); - } - int minfreq = Integer.MAX_VALUE; - for (Map.Entry it : freq.entrySet()) { - minfreq = Math.min(minfreq, it.getValue()); + int[] freq = new int[10]; + String numStr = String.valueOf(n); + for (char c : numStr.toCharArray()) { + freq[c - '0']++; } - int result = 10; - for (Map.Entry it : freq.entrySet()) { - if (it.getValue() == minfreq) { - result = Math.min(result, it.getKey()); + int minFreq = Integer.MAX_VALUE; + int result = -1; + for (int d = 0; d <= 9; d++) { + if (freq[d] == 0) { + continue; + } + if (freq[d] < minFreq) { + minFreq = freq[d]; + result = d; + } else if (freq[d] == minFreq && d < result) { + result = d; } } return result; diff --git a/src/main/java/g3601_3700/s3664_two_letter_card_game/Solution.java b/src/main/java/g3601_3700/s3664_two_letter_card_game/Solution.java index 1c189f434..0c43680a5 100644 --- a/src/main/java/g3601_3700/s3664_two_letter_card_game/Solution.java +++ b/src/main/java/g3601_3700/s3664_two_letter_card_game/Solution.java @@ -1,6 +1,6 @@ package g3601_3700.s3664_two_letter_card_game; -// #Medium #Biweekly_Contest_164 #2025_08_31_Time_8_ms_(99.42%)_Space_60.09_MB_(52.34%) +// #Medium #Biweekly_Contest_164 #2025_09_06_Time_8_ms_(98.82%)_Space_60.21_MB_(45.56%) public class Solution { public int score(String[] cards, char x) { diff --git a/src/main/java/g3601_3700/s3665_twisted_mirror_path_count/Solution.java b/src/main/java/g3601_3700/s3665_twisted_mirror_path_count/Solution.java index 1803645cb..2f7fab0f0 100644 --- a/src/main/java/g3601_3700/s3665_twisted_mirror_path_count/Solution.java +++ b/src/main/java/g3601_3700/s3665_twisted_mirror_path_count/Solution.java @@ -1,46 +1,37 @@ package g3601_3700.s3665_twisted_mirror_path_count; -// #Medium #Biweekly_Contest_164 #2025_08_31_Time_204_ms_(100.00%)_Space_86.33_MB_(100.00%) - -import java.util.Arrays; +// #Medium #Biweekly_Contest_164 #2025_09_06_Time_28_ms_(100.00%)_Space_86.70_MB_(69.78%) public class Solution { - private static final int MOD = 1000000007; - public int uniquePaths(int[][] grid) { + // 0 right, 1 down int n = grid.length; int m = grid[0].length; - int[][][] dp = new int[n][m][2]; - for (int i = 0; i < n; i++) { - for (int j = 0; j < m; j++) { - Arrays.fill(dp[i][j], -1); + int mod = 1_000_000_007; + int[] dp = new int[m]; + dp[0] = 1; + for (int j = 1; j < m; j++) { + if (grid[0][j - 1] == 0) { + dp[j] = dp[j - 1]; } } - return f(0, 0, 0, grid, n, m, dp); - } - - private int f(int i, int j, int dir, int[][] grid, int n, int m, int[][][] dp) { - if (i == n - 1 && j == m - 1) { - return 1; - } - if (i >= n || j >= m) { - return 0; - } - if (dp[i][j][dir] != -1) { - return dp[i][j][dir]; - } - long ways = 0; - if (grid[i][j] == 1) { - if (dir == 0) { - ways = f(i + 1, j, 1, grid, n, m, dp); - } else { - ways = f(i, j + 1, 0, grid, n, m, dp); + for (int i = 1; i < n; i++) { + int[] next = new int[m]; + if (grid[i - 1][0] == 0 && grid[i][0] == 0) { + next[0] = dp[0]; + } + for (int j = 1; j < m; j++) { + if (grid[i][j] == 0) { + next[j] = (next[j] + dp[j]) % mod; + } + if (grid[i][j - 1] == 0) { + next[j] = (next[j] + next[j - 1]) % mod; + } else { + next[j] = (next[j] + dp[j - 1]) % mod; + } } - } else { - ways += f(i + 1, j, 1, grid, n, m, dp); - ways += f(i, j + 1, 0, grid, n, m, dp); + dp = next; } - dp[i][j][dir] = (int) ways % MOD; - return dp[i][j][dir]; + return dp[m - 1]; } } diff --git a/src/main/java/g3601_3700/s3666_minimum_operations_to_equalize_binary_string/Solution.java b/src/main/java/g3601_3700/s3666_minimum_operations_to_equalize_binary_string/Solution.java index eebfb79a3..811c0ed30 100644 --- a/src/main/java/g3601_3700/s3666_minimum_operations_to_equalize_binary_string/Solution.java +++ b/src/main/java/g3601_3700/s3666_minimum_operations_to_equalize_binary_string/Solution.java @@ -1,63 +1,106 @@ package g3601_3700.s3666_minimum_operations_to_equalize_binary_string; -// #Hard #Biweekly_Contest_164 #2025_08_31_Time_22_ms_(100.00%)_Space_45.62_MB_(100.00%) - -import java.util.ArrayDeque; -import java.util.Queue; +// #Hard #Biweekly_Contest_164 #2025_09_06_Time_4_ms_(100.00%)_Space_46.11_MB_(31.99%) public class Solution { public int minOperations(String s, int k) { - int zeros = s.chars().map(x -> x == '0' ? 1 : 0).sum(); - if ((zeros % k) == 0) { - return zeros / k; + int zero = 0; + for (char chr : s.toCharArray()) { + zero += '1' - chr; + } + if (zero % 2 != 0 && k % 2 == 0) { + return -1; + } + if (zero % k == 0) { + return zero / k; } - int n = s.length(); - Queue q = new ArrayDeque<>(); - q.add(zeros); - int res = 1; - // use bounds for optimization - int[][] bounds = new int[2][2]; - bounds[zeros & 1][0] = bounds[zeros & 1][1] = zeros; - bounds[1 - (zeros & 1)][0] = Integer.MAX_VALUE; - bounds[1 - (zeros & 1)][1] = Integer.MIN_VALUE; - while (!q.isEmpty()) { - // find min number of zeros and max number of zeros in this round - int minv = Integer.MAX_VALUE; - int maxv = Integer.MIN_VALUE; - for (int len = q.size(); len > 0; len--) { - int h = q.poll(); - int t = n - h; - int x = Math.min(h, k); - if (t >= k - x) { - int fst = h - x + (k - x); - minv = Math.min(minv, fst); - maxv = Math.max(maxv, fst); - } - x = Math.min(t, k); - if (h >= k - x) { - int snd = h - (k - x) + x; - minv = Math.min(minv, snd); - maxv = Math.max(maxv, snd); - } - } - // possible children are sequence of equal difference 2 - int ind = minv & 1; - int temp = minv; - while (temp <= maxv) { - if ((temp % k) == 0) { - return res + temp / k; - } - if (temp < bounds[ind][0] || temp > bounds[ind][1]) { - q.add(temp); - temp += 2; - } else { - temp = bounds[ind][1] + 2; - } - } - bounds[ind][0] = Math.min(bounds[ind][0], minv); - bounds[ind][1] = Math.max(bounds[ind][1], maxv); + if (k % 2 == 0) { + return get(zero, s.length(), k); + } else { + return get1(zero, s.length(), k); + } + } + + private int get(int zero, int sum, int k) { + int l = zero; + int r = zero; + int res = 0; + while (true) { + if (l == 0) { + return res; + } + int lNext; + if (l >= k) { + lNext = l - k; + } else if (r >= k) { + lNext = 0; + } else { + lNext = k - r; + } + int rNext; + int a = sum - r; + int b = sum - l; + if (a >= k) { + rNext = r + k; + } else if (b >= k) { + rNext = sum; + } else { + rNext = l + b - (k - b); + } + if (l == lNext && r == rNext) { + break; + } + if (l > lNext) { + l = lNext; + } + if (r < rNext) { + r = rNext; + } res++; } return -1; } + + private int get1(int zero, int sum, int k) { + int[] l = {Integer.MAX_VALUE, zero}; + int[] r = {Integer.MIN_VALUE, zero}; + int res = 0; + while (true) { + int idx1 = res % 2; + int idx = 1 - idx1; + int lNext; + int offset = 1 - l[idx] % 2; + if (l[idx] >= k) { + lNext = l[idx] - k; + } else if (r[idx] >= k) { + lNext = offset; + } else { + lNext = k - r[idx]; + } + int rNext; + int a = sum - r[idx]; + int b = sum - l[idx]; + if (a >= k) { + rNext = r[idx] + k; + } else if (b >= k) { + rNext = sum - offset; + } else { + rNext = l[idx] + b - (k - b); + } + if (l[idx1] == lNext && r[idx1] == rNext) { + break; + } + if (l[idx1] > lNext) { + l[idx1] = lNext; + } + if (r[idx1] < rNext) { + r[idx1] = rNext; + } + res++; + if (l[idx1] == 0) { + return res; + } + } + return -1; + } } diff --git a/src/main/java/g3601_3700/s3668_restore_finishing_order/Solution.java b/src/main/java/g3601_3700/s3668_restore_finishing_order/Solution.java index a4a707119..c6577e80c 100644 --- a/src/main/java/g3601_3700/s3668_restore_finishing_order/Solution.java +++ b/src/main/java/g3601_3700/s3668_restore_finishing_order/Solution.java @@ -1,6 +1,6 @@ package g3601_3700.s3668_restore_finishing_order; -// #Easy #Weekly_Contest_465 #2025_08_31_Time_1_ms_(100.00%)_Space_45.15_MB_(49.19%) +// #Easy #Weekly_Contest_465 #2025_09_06_Time_1_ms_(100.00%)_Space_45.18_MB_(44.72%) public class Solution { public int[] recoverOrder(int[] order, int[] friends) { diff --git a/src/main/java/g3601_3700/s3669_balanced_k_factor_decomposition/Solution.java b/src/main/java/g3601_3700/s3669_balanced_k_factor_decomposition/Solution.java index 92817a003..355551b77 100644 --- a/src/main/java/g3601_3700/s3669_balanced_k_factor_decomposition/Solution.java +++ b/src/main/java/g3601_3700/s3669_balanced_k_factor_decomposition/Solution.java @@ -1,6 +1,6 @@ package g3601_3700.s3669_balanced_k_factor_decomposition; -// #Medium #Weekly_Contest_465 #2025_08_31_Time_13_ms_(73.81%)_Space_45.35_MB_(27.49%) +// #Medium #Weekly_Contest_465 #2025_09_06_Time_13_ms_(78.36%)_Space_45.64_MB_(10.38%) import java.util.ArrayList; import java.util.Collections; diff --git a/src/main/java/g3601_3700/s3670_maximum_product_of_two_integers_with_no_common_bits/Solution.java b/src/main/java/g3601_3700/s3670_maximum_product_of_two_integers_with_no_common_bits/Solution.java index 9b9a1315c..cf554fd9f 100644 --- a/src/main/java/g3601_3700/s3670_maximum_product_of_two_integers_with_no_common_bits/Solution.java +++ b/src/main/java/g3601_3700/s3670_maximum_product_of_two_integers_with_no_common_bits/Solution.java @@ -1,6 +1,6 @@ package g3601_3700.s3670_maximum_product_of_two_integers_with_no_common_bits; -// #Medium #Weekly_Contest_465 #2025_08_31_Time_138_ms_(99.69%)_Space_64.47_MB_(29.81%) +// #Medium #Weekly_Contest_465 #2025_09_06_Time_151_ms_(99.28%)_Space_64.23_MB_(47.58%) public class Solution { public long maxProduct(int[] nums) { diff --git a/src/main/java/g3601_3700/s3671_sum_of_beautiful_subsequences/Solution.java b/src/main/java/g3601_3700/s3671_sum_of_beautiful_subsequences/Solution.java index 6aa7d9708..598325a7d 100644 --- a/src/main/java/g3601_3700/s3671_sum_of_beautiful_subsequences/Solution.java +++ b/src/main/java/g3601_3700/s3671_sum_of_beautiful_subsequences/Solution.java @@ -1,6 +1,6 @@ package g3601_3700.s3671_sum_of_beautiful_subsequences; -// #Hard #Weekly_Contest_465 #2025_08_31_Time_224_ms_(99.03%)_Space_56.07_MB_(89.32%) +// #Hard #Weekly_Contest_465 #2025_09_06_Time_233_ms_(96.31%)_Space_62.03_MB_(69.80%) public class Solution { private static final int MOD = 1000000007; From 5e9caab053b410fba7a1b0be3c7ef5378b8e7e89 Mon Sep 17 00:00:00 2001 From: Valentyn Kolesnikov Date: Sat, 6 Sep 2025 13:23:08 +0300 Subject: [PATCH 5/8] Enabled gradle cache --- gradle.properties | 1 + 1 file changed, 1 insertion(+) diff --git a/gradle.properties b/gradle.properties index aab906524..055bf6cf6 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,2 +1,3 @@ sonar.coverage.jacoco.xmlReportPaths=build/jacoco/test/jacocoTestReport.xml org.gradle.jvmargs=-Xms512m -Xmx2048m +org.gradle.configuration-cache=true From 8ac4663065b97cd4aa2bb58d969698448496c04c Mon Sep 17 00:00:00 2001 From: Valentyn Kolesnikov Date: Sat, 6 Sep 2025 13:29:43 +0300 Subject: [PATCH 6/8] Improved task --- .../Solution.java | 126 +++++------------- 1 file changed, 32 insertions(+), 94 deletions(-) diff --git a/src/main/java/g3601_3700/s3666_minimum_operations_to_equalize_binary_string/Solution.java b/src/main/java/g3601_3700/s3666_minimum_operations_to_equalize_binary_string/Solution.java index 811c0ed30..44a7b28e5 100644 --- a/src/main/java/g3601_3700/s3666_minimum_operations_to_equalize_binary_string/Solution.java +++ b/src/main/java/g3601_3700/s3666_minimum_operations_to_equalize_binary_string/Solution.java @@ -1,106 +1,44 @@ package g3601_3700.s3666_minimum_operations_to_equalize_binary_string; -// #Hard #Biweekly_Contest_164 #2025_09_06_Time_4_ms_(100.00%)_Space_46.11_MB_(31.99%) +// #Hard #Biweekly_Contest_164 #2025_09_06_Time_6_ms_(83.87%)_Space_45.74_MB_(64.52%) public class Solution { public int minOperations(String s, int k) { - int zero = 0; - for (char chr : s.toCharArray()) { - zero += '1' - chr; - } - if (zero % 2 != 0 && k % 2 == 0) { - return -1; - } - if (zero % k == 0) { - return zero / k; + int n = s.length(); + int cnt0 = 0; + for (char c : s.toCharArray()) { + if (c == '0') { + cnt0++; + } } - if (k % 2 == 0) { - return get(zero, s.length(), k); - } else { - return get1(zero, s.length(), k); + if (cnt0 == 0) { + return 0; } - } - - private int get(int zero, int sum, int k) { - int l = zero; - int r = zero; - int res = 0; - while (true) { - if (l == 0) { - return res; - } - int lNext; - if (l >= k) { - lNext = l - k; - } else if (r >= k) { - lNext = 0; - } else { - lNext = k - r; - } - int rNext; - int a = sum - r; - int b = sum - l; - if (a >= k) { - rNext = r + k; - } else if (b >= k) { - rNext = sum; - } else { - rNext = l + b - (k - b); - } - if (l == lNext && r == rNext) { - break; - } - if (l > lNext) { - l = lNext; - } - if (r < rNext) { - r = rNext; - } - res++; + if (k == n) { + return cnt0 == n ? 1 : -1; } - return -1; - } - - private int get1(int zero, int sum, int k) { - int[] l = {Integer.MAX_VALUE, zero}; - int[] r = {Integer.MIN_VALUE, zero}; - int res = 0; - while (true) { - int idx1 = res % 2; - int idx = 1 - idx1; - int lNext; - int offset = 1 - l[idx] % 2; - if (l[idx] >= k) { - lNext = l[idx] - k; - } else if (r[idx] >= k) { - lNext = offset; - } else { - lNext = k - r[idx]; - } - int rNext; - int a = sum - r[idx]; - int b = sum - l[idx]; - if (a >= k) { - rNext = r[idx] + k; - } else if (b >= k) { - rNext = sum - offset; - } else { - rNext = l[idx] + b - (k - b); - } - if (l[idx1] == lNext && r[idx1] == rNext) { - break; - } - if (l[idx1] > lNext) { - l[idx1] = lNext; - } - if (r[idx1] < rNext) { - r[idx1] = rNext; - } - res++; - if (l[idx1] == 0) { - return res; + int kP = k & 1; + int needP = cnt0 & 1; + long best = Long.MAX_VALUE; + for (int p = 0; p <= 1; p++) { + if ((p * kP) % 2 != needP) { + continue; + } + long mismatch = (p == 0) ? cnt0 : (n - cnt0); + long b1 = (cnt0 + k - 1L) / k; + long b2; + b2 = (mismatch + (n - k) - 1L) / (n - k); + long lb = Math.max(b1, b2); + if (lb < 1) { + lb = 1; + } + if ((lb & 1) != p) { + lb++; + } + if (lb < best) { + best = lb; } } - return -1; + return best == Long.MAX_VALUE ? -1 : (int) best; } } From 4cdcb0688a8fd5e1f3ab139c8c3fac32c79d6b72 Mon Sep 17 00:00:00 2001 From: Valentyn Kolesnikov Date: Sat, 6 Sep 2025 13:40:49 +0300 Subject: [PATCH 7/8] Added tests --- .../SolutionTest.java | 80 +++++++++++++++++++ 1 file changed, 80 insertions(+) diff --git a/src/test/java/g3601_3700/s3666_minimum_operations_to_equalize_binary_string/SolutionTest.java b/src/test/java/g3601_3700/s3666_minimum_operations_to_equalize_binary_string/SolutionTest.java index acab41602..1946594d7 100644 --- a/src/test/java/g3601_3700/s3666_minimum_operations_to_equalize_binary_string/SolutionTest.java +++ b/src/test/java/g3601_3700/s3666_minimum_operations_to_equalize_binary_string/SolutionTest.java @@ -20,4 +20,84 @@ void minOperations2() { void minOperations3() { assertThat(new Solution().minOperations("101", 2), equalTo(-1)); } + + @Test + void minOperations4() { + String s = "111111"; + int k = 3; + int result = new Solution().minOperations(s, k); + assertThat(result, equalTo(0)); + } + + @Test + void minOperations5() { + String s = "000000"; + int k = 6; + int result = new Solution().minOperations(s, k); + assertThat(result, equalTo(1)); + } + + @Test + void minOperations6() { + String s = "000111"; + int k = 6; + int result = new Solution().minOperations(s, k); + assertThat(result, equalTo(-1)); + } + + @Test + void minOperations7() { + String s = "0011"; + int k = 3; + int result = new Solution().minOperations(s, k); + assertThat(result, equalTo(2)); + } + + @Test + void minOperations8() { + String s = "000011"; + int k = 4; + int result = new Solution().minOperations(s, k); + assertThat(result, equalTo(1)); + } + + @Test + void minOperations9() { + String s = "000111"; + int k = 2; + int result = new Solution().minOperations(s, k); + assertThat(result, equalTo(-1)); + } + + @Test + void minOperations10() { + String s = "001100"; + int k = 4; + int result = new Solution().minOperations(s, k); + assertThat(result, equalTo(1)); + } + + @Test + void minOperations11() { + String s = "000100"; + int k = 3; + int result = new Solution().minOperations(s, k); + assertThat(result, equalTo(3)); + } + + @Test + void minOperations12() { + String s = "111111"; + int k = 4; + int result = new Solution().minOperations(s, k); + assertThat(result, equalTo(0)); + } + + @Test + void minOperations13() { + String s = "001001"; + int k = 4; + int result = new Solution().minOperations(s, k); + assertThat(result, equalTo(1)); + } } From fe6d0831bb74cf00bad4c132554ca95d19468c20 Mon Sep 17 00:00:00 2001 From: Valentyn Kolesnikov Date: Sat, 6 Sep 2025 13:48:25 +0300 Subject: [PATCH 8/8] Fixed sonar --- .../SolutionTest.java | 40 +++++-------------- 1 file changed, 10 insertions(+), 30 deletions(-) diff --git a/src/test/java/g3601_3700/s3666_minimum_operations_to_equalize_binary_string/SolutionTest.java b/src/test/java/g3601_3700/s3666_minimum_operations_to_equalize_binary_string/SolutionTest.java index 1946594d7..ad8260430 100644 --- a/src/test/java/g3601_3700/s3666_minimum_operations_to_equalize_binary_string/SolutionTest.java +++ b/src/test/java/g3601_3700/s3666_minimum_operations_to_equalize_binary_string/SolutionTest.java @@ -23,81 +23,61 @@ void minOperations3() { @Test void minOperations4() { - String s = "111111"; int k = 3; - int result = new Solution().minOperations(s, k); - assertThat(result, equalTo(0)); + assertThat(new Solution().minOperations("111111", k), equalTo(0)); } @Test void minOperations5() { - String s = "000000"; int k = 6; - int result = new Solution().minOperations(s, k); - assertThat(result, equalTo(1)); + assertThat(new Solution().minOperations("000000", k), equalTo(1)); } @Test void minOperations6() { - String s = "000111"; int k = 6; - int result = new Solution().minOperations(s, k); - assertThat(result, equalTo(-1)); + assertThat(new Solution().minOperations("000111", k), equalTo(-1)); } @Test void minOperations7() { - String s = "0011"; int k = 3; - int result = new Solution().minOperations(s, k); - assertThat(result, equalTo(2)); + assertThat(new Solution().minOperations("0011", k), equalTo(2)); } @Test void minOperations8() { - String s = "000011"; int k = 4; - int result = new Solution().minOperations(s, k); - assertThat(result, equalTo(1)); + assertThat(new Solution().minOperations("000011", k), equalTo(1)); } @Test void minOperations9() { - String s = "000111"; int k = 2; - int result = new Solution().minOperations(s, k); - assertThat(result, equalTo(-1)); + assertThat(new Solution().minOperations("000111", k), equalTo(-1)); } @Test void minOperations10() { - String s = "001100"; int k = 4; - int result = new Solution().minOperations(s, k); - assertThat(result, equalTo(1)); + assertThat(new Solution().minOperations("001100", k), equalTo(1)); } @Test void minOperations11() { - String s = "000100"; int k = 3; - int result = new Solution().minOperations(s, k); - assertThat(result, equalTo(3)); + assertThat(new Solution().minOperations("000100", k), equalTo(3)); } @Test void minOperations12() { - String s = "111111"; int k = 4; - int result = new Solution().minOperations(s, k); - assertThat(result, equalTo(0)); + assertThat(new Solution().minOperations("111111", k), equalTo(0)); } @Test void minOperations13() { - String s = "001001"; int k = 4; - int result = new Solution().minOperations(s, k); - assertThat(result, equalTo(1)); + assertThat(new Solution().minOperations("001001", k), equalTo(1)); } }