diff --git a/src/main/java/g3301_3400/s3309_maximum_possible_number_by_binary_concatenation/Solution.java b/src/main/java/g3301_3400/s3309_maximum_possible_number_by_binary_concatenation/Solution.java new file mode 100644 index 000000000..c94b7820b --- /dev/null +++ b/src/main/java/g3301_3400/s3309_maximum_possible_number_by_binary_concatenation/Solution.java @@ -0,0 +1,45 @@ +package g3301_3400.s3309_maximum_possible_number_by_binary_concatenation; + +// #Medium #Array #Bit_Manipulation #Enumeration +// #2024_10_08_Time_3_ms_(97.01%)_Space_42.2_MB_(90.32%) + +public class Solution { + private String result = "0"; + + public int maxGoodNumber(int[] nums) { + boolean[] visited = new boolean[nums.length]; + StringBuilder sb = new StringBuilder(); + solve(nums, visited, 0, sb); + int score = 0; + int val; + for (char c : result.toCharArray()) { + val = c - '0'; + score *= 2; + score += val; + } + return score; + } + + private void solve(int[] nums, boolean[] visited, int pos, StringBuilder sb) { + if (pos == nums.length) { + String val = sb.toString(); + if ((result.length() == val.length() && result.compareTo(val) < 0) + || val.length() > result.length()) { + result = val; + } + return; + } + String cur; + for (int i = 0; i < nums.length; ++i) { + if (visited[i]) { + continue; + } + visited[i] = true; + cur = Integer.toBinaryString(nums[i]); + sb.append(cur); + solve(nums, visited, pos + 1, sb); + sb.setLength(sb.length() - cur.length()); + visited[i] = false; + } + } +} diff --git a/src/main/java/g3301_3400/s3309_maximum_possible_number_by_binary_concatenation/readme.md b/src/main/java/g3301_3400/s3309_maximum_possible_number_by_binary_concatenation/readme.md new file mode 100644 index 000000000..4e6ecf1f1 --- /dev/null +++ b/src/main/java/g3301_3400/s3309_maximum_possible_number_by_binary_concatenation/readme.md @@ -0,0 +1,34 @@ +3309\. Maximum Possible Number by Binary Concatenation + +Medium + +You are given an array of integers `nums` of size 3. + +Return the **maximum** possible number whose _binary representation_ can be formed by **concatenating** the _binary representation_ of **all** elements in `nums` in some order. + +**Note** that the binary representation of any number _does not_ contain leading zeros. + +**Example 1:** + +**Input:** nums = [1,2,3] + +**Output:** 30 + +**Explanation:** + +Concatenate the numbers in the order `[3, 1, 2]` to get the result `"11110"`, which is the binary representation of 30. + +**Example 2:** + +**Input:** nums = [2,8,16] + +**Output:** 1296 + +**Explanation:** + +Concatenate the numbers in the order `[2, 8, 16]` to get the result `"10100010000"`, which is the binary representation of 1296. + +**Constraints:** + +* `nums.length == 3` +* `1 <= nums[i] <= 127` \ No newline at end of file diff --git a/src/main/java/g3301_3400/s3310_remove_methods_from_project/Solution.java b/src/main/java/g3301_3400/s3310_remove_methods_from_project/Solution.java new file mode 100644 index 000000000..be0ff54d5 --- /dev/null +++ b/src/main/java/g3301_3400/s3310_remove_methods_from_project/Solution.java @@ -0,0 +1,77 @@ +package g3301_3400.s3310_remove_methods_from_project; + +// #Medium #Graph #Depth_First_Search #Breadth_First_Search +// #2024_10_08_Time_41_ms_(99.76%)_Space_154.8_MB_(55.29%) + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +public class Solution { + private int[][] graph; + private boolean[] suspicious; + private boolean[] visited; + + public List remainingMethods(int n, int k, int[][] invocations) { + pack(invocations, n); + suspicious = new boolean[n]; + visited = new boolean[n]; + dfs(k, true); + Arrays.fill(visited, false); + for (int i = 0; i < n; i++) { + if (!suspicious[i] && dfs2(i)) { + Arrays.fill(visited, false); + dfs(k, false); + break; + } + } + ArrayList rst = new ArrayList<>(); + for (int i = 0; i < n; i++) { + if (!suspicious[i]) { + rst.add(i); + } + } + return rst; + } + + public void dfs(int u, boolean sus) { + if (visited[u]) { + return; + } + visited[u] = true; + suspicious[u] = sus; + for (int v : graph[u]) { + dfs(v, sus); + } + } + + public boolean dfs2(int u) { + if (suspicious[u]) { + return true; + } + if (visited[u]) { + return false; + } + visited[u] = true; + for (int v : graph[u]) { + if (dfs2(v)) { + return true; + } + } + return false; + } + + private void pack(int[][] edges, int n) { + int[] adj = new int[n]; + for (int[] edge : edges) { + adj[edge[0]]++; + } + graph = new int[n][]; + for (int i = 0; i < n; i++) { + graph[i] = new int[adj[i]]; + } + for (int[] edge : edges) { + graph[edge[0]][--adj[edge[0]]] = edge[1]; + } + } +} diff --git a/src/main/java/g3301_3400/s3310_remove_methods_from_project/readme.md b/src/main/java/g3301_3400/s3310_remove_methods_from_project/readme.md new file mode 100644 index 000000000..6a49b6989 --- /dev/null +++ b/src/main/java/g3301_3400/s3310_remove_methods_from_project/readme.md @@ -0,0 +1,59 @@ +3310\. Remove Methods From Project + +Medium + +You are maintaining a project that has `n` methods numbered from `0` to `n - 1`. + +You are given two integers `n` and `k`, and a 2D integer array `invocations`, where invocations[i] = [ai, bi] indicates that method ai invokes method bi. + +There is a known bug in method `k`. Method `k`, along with any method invoked by it, either **directly** or **indirectly**, are considered **suspicious** and we aim to remove them. + +A group of methods can only be removed if no method **outside** the group invokes any methods **within** it. + +Return an array containing all the remaining methods after removing all the **suspicious** methods. You may return the answer in _any order_. If it is not possible to remove **all** the suspicious methods, **none** should be removed. + +**Example 1:** + +**Input:** n = 4, k = 1, invocations = [[1,2],[0,1],[3,2]] + +**Output:** [0,1,2,3] + +**Explanation:** + +![](https://assets.leetcode.com/uploads/2024/07/18/graph-2.png) + +Method 2 and method 1 are suspicious, but they are directly invoked by methods 3 and 0, which are not suspicious. We return all elements without removing anything. + +**Example 2:** + +**Input:** n = 5, k = 0, invocations = [[1,2],[0,2],[0,1],[3,4]] + +**Output:** [3,4] + +**Explanation:** + +![](https://assets.leetcode.com/uploads/2024/07/18/graph-3.png) + +Methods 0, 1, and 2 are suspicious and they are not directly invoked by any other method. We can remove them. + +**Example 3:** + +**Input:** n = 3, k = 2, invocations = [[1,2],[0,1],[2,0]] + +**Output:** [] + +**Explanation:** + +![](https://assets.leetcode.com/uploads/2024/07/20/graph.png) + +All methods are suspicious. We can remove them. + +**Constraints:** + +* 1 <= n <= 105 +* `0 <= k <= n - 1` +* 0 <= invocations.length <= 2 * 105 +* invocations[i] == [ai, bi] +* 0 <= ai, bi <= n - 1 +* ai != bi +* `invocations[i] != invocations[j]` \ No newline at end of file diff --git a/src/main/java/g3301_3400/s3311_construct_2d_grid_matching_graph_layout/Solution.java b/src/main/java/g3301_3400/s3311_construct_2d_grid_matching_graph_layout/Solution.java new file mode 100644 index 000000000..508be3786 --- /dev/null +++ b/src/main/java/g3301_3400/s3311_construct_2d_grid_matching_graph_layout/Solution.java @@ -0,0 +1,125 @@ +package g3301_3400.s3311_construct_2d_grid_matching_graph_layout; + +// #Hard #Array #Hash_Table #Matrix #Graph #2024_10_08_Time_43_ms_(94.34%)_Space_103.6_MB_(79.25%) + +import java.util.ArrayList; + +@SuppressWarnings("unchecked") +public class Solution { + public int[][] constructGridLayout(int n, int[][] edges) { + final int[] cs = new int[n]; + final ArrayList[] als = new ArrayList[n]; + for (int i = 0; i < n; ++i) { + als[i] = new ArrayList<>(); + } + for (int[] e : edges) { + cs[e[0]]++; + cs[e[1]]++; + als[e[0]].add(e[1]); + als[e[1]].add(e[0]); + } + int min = 4; + for (int a : cs) { + min = Math.min(min, a); + } + final boolean[] seen = new boolean[n]; + int[][] res; + int st = 0; + for (int i = 0; i < n; ++i) { + if (cs[i] == min) { + st = i; + break; + } + } + if (min == 1) { + res = new int[1][n]; + for (int i = 0; i < n; ++i) { + res[0][i] = st; + seen[st] = true; + if (i + 1 < n) { + for (int a : als[st]) { + if (!seen[a]) { + st = a; + break; + } + } + } + } + return res; + } + int row2 = -1; + for (int a : als[st]) { + if (cs[a] == min) { + row2 = a; + break; + } + } + if (row2 >= 0) { + return getInts(n, st, row2, seen, als); + } + return getInts(n, seen, st, als, cs); + } + + private int[][] getInts(int n, boolean[] seen, int st, ArrayList[] als, int[] cs) { + int[][] res; + final ArrayList al = new ArrayList<>(); + boolean f = true; + seen[st] = true; + al.add(st); + while (f) { + f = false; + for (int a : als[st]) { + if (!seen[a] && cs[a] <= 3) { + seen[a] = true; + al.add(a); + if (cs[a] == 3) { + f = true; + st = a; + } + break; + } + } + } + res = new int[n / al.size()][al.size()]; + for (int i = 0; i < res[0].length; ++i) { + res[0][i] = al.get(i); + } + for (int i = 1; i < res.length; ++i) { + for (int j = 0; j < res[0].length; ++j) { + for (int a : als[res[i - 1][j]]) { + if (!seen[a]) { + res[i][j] = a; + seen[a] = true; + break; + } + } + } + } + return res; + } + + private int[][] getInts(int n, int st, int row2, boolean[] seen, ArrayList[] als) { + int[][] res; + res = new int[2][n / 2]; + res[0][0] = st; + res[1][0] = row2; + seen[st] = seen[row2] = true; + for (int i = 1; i < res[0].length; ++i) { + for (int a : als[res[0][i - 1]]) { + if (!seen[a]) { + res[0][i] = a; + seen[a] = true; + break; + } + } + for (int a : als[res[1][i - 1]]) { + if (!seen[a]) { + res[1][i] = a; + seen[a] = true; + break; + } + } + } + return res; + } +} diff --git a/src/main/java/g3301_3400/s3311_construct_2d_grid_matching_graph_layout/readme.md b/src/main/java/g3301_3400/s3311_construct_2d_grid_matching_graph_layout/readme.md new file mode 100644 index 000000000..a8ef87b54 --- /dev/null +++ b/src/main/java/g3301_3400/s3311_construct_2d_grid_matching_graph_layout/readme.md @@ -0,0 +1,53 @@ +3311\. Construct 2D Grid Matching Graph Layout + +Hard + +You are given a 2D integer array `edges` representing an **undirected** graph having `n` nodes, where edges[i] = [ui, vi] denotes an edge between nodes ui and vi. + +Construct a 2D grid that satisfies these conditions: + +* The grid contains **all nodes** from `0` to `n - 1` in its cells, with each node appearing exactly **once**. +* Two nodes should be in adjacent grid cells (**horizontally** or **vertically**) **if and only if** there is an edge between them in `edges`. + +It is guaranteed that `edges` can form a 2D grid that satisfies the conditions. + +Return a 2D integer array satisfying the conditions above. If there are multiple solutions, return _any_ of them. + +**Example 1:** + +**Input:** n = 4, edges = [[0,1],[0,2],[1,3],[2,3]] + +**Output:** [[3,1],[2,0]] + +**Explanation:** + +![](https://assets.leetcode.com/uploads/2024/08/11/screenshot-from-2024-08-11-14-07-59.png) + +**Example 2:** + +**Input:** n = 5, edges = [[0,1],[1,3],[2,3],[2,4]] + +**Output:** [[4,2,3,1,0]] + +**Explanation:** + +![](https://assets.leetcode.com/uploads/2024/08/11/screenshot-from-2024-08-11-14-06-02.png) + +**Example 3:** + +**Input:** n = 9, edges = [[0,1],[0,4],[0,5],[1,7],[2,3],[2,4],[2,5],[3,6],[4,6],[4,7],[6,8],[7,8]] + +**Output:** [[8,6,3],[7,4,2],[1,0,5]] + +**Explanation:** + +![](https://assets.leetcode.com/uploads/2024/08/11/screenshot-from-2024-08-11-14-06-38.png) + +**Constraints:** + +* 2 <= n <= 5 * 104 +* 1 <= edges.length <= 105 +* edges[i] = [ui, vi] +* 0 <= ui < vi < n +* All the edges are distinct. +* The input is generated such that `edges` can form a 2D grid that satisfies the conditions. \ No newline at end of file diff --git a/src/main/java/g3301_3400/s3312_sorted_gcd_pair_queries/Solution.java b/src/main/java/g3301_3400/s3312_sorted_gcd_pair_queries/Solution.java new file mode 100644 index 000000000..21725295e --- /dev/null +++ b/src/main/java/g3301_3400/s3312_sorted_gcd_pair_queries/Solution.java @@ -0,0 +1,51 @@ +package g3301_3400.s3312_sorted_gcd_pair_queries; + +// #Hard #Array #Hash_Table #Math #Binary_Search #Prefix_Sum #Counting #Number_Theory #Combinatorics +// #2024_10_08_Time_29_ms_(94.69%)_Space_63.4_MB_(63.72%) + +public class Solution { + public int[] gcdValues(int[] nums, long[] queries) { + int max = 1; + for (int num : nums) { + max = Math.max(max, num); + } + long[] gcdDp = new long[max + 1]; + for (int num : nums) { + gcdDp[num]++; + } + for (int i = 1; i <= max; i++) { + long count = 0; + for (int j = i; j <= max; j = j + i) { + count += gcdDp[j]; + } + gcdDp[i] = ((count - 1) * count) / 2; + } + for (int i = max; i > 0; i--) { + for (int j = i + i; j <= max; j = j + i) { + gcdDp[i] -= gcdDp[j]; + } + } + for (int i = 1; i <= max; i++) { + gcdDp[i] += gcdDp[i - 1]; + } + int[] result = new int[queries.length]; + for (int i = 0; i < queries.length; i++) { + result[i] = binarySearch(max, gcdDp, queries[i] + 1); + } + return result; + } + + private int binarySearch(int n, long[] arr, long val) { + int l = 1; + int r = n; + while (l < r) { + int mid = l + (r - l) / 2; + if (arr[mid] < val) { + l = mid + 1; + } else { + r = mid; + } + } + return l; + } +} diff --git a/src/main/java/g3301_3400/s3312_sorted_gcd_pair_queries/readme.md b/src/main/java/g3301_3400/s3312_sorted_gcd_pair_queries/readme.md new file mode 100644 index 000000000..64880b0bf --- /dev/null +++ b/src/main/java/g3301_3400/s3312_sorted_gcd_pair_queries/readme.md @@ -0,0 +1,54 @@ +3312\. Sorted GCD Pair Queries + +Hard + +You are given an integer array `nums` of length `n` and an integer array `queries`. + +Let `gcdPairs` denote an array obtained by calculating the GCD of all possible pairs `(nums[i], nums[j])`, where `0 <= i < j < n`, and then sorting these values in **ascending** order. + +For each query `queries[i]`, you need to find the element at index `queries[i]` in `gcdPairs`. + +Return an integer array `answer`, where `answer[i]` is the value at `gcdPairs[queries[i]]` for each query. + +The term `gcd(a, b)` denotes the **greatest common divisor** of `a` and `b`. + +**Example 1:** + +**Input:** nums = [2,3,4], queries = [0,2,2] + +**Output:** [1,2,2] + +**Explanation:** + +`gcdPairs = [gcd(nums[0], nums[1]), gcd(nums[0], nums[2]), gcd(nums[1], nums[2])] = [1, 2, 1]`. + +After sorting in ascending order, `gcdPairs = [1, 1, 2]`. + +So, the answer is `[gcdPairs[queries[0]], gcdPairs[queries[1]], gcdPairs[queries[2]]] = [1, 2, 2]`. + +**Example 2:** + +**Input:** nums = [4,4,2,1], queries = [5,3,1,0] + +**Output:** [4,2,1,1] + +**Explanation:** + +`gcdPairs` sorted in ascending order is `[1, 1, 1, 2, 2, 4]`. + +**Example 3:** + +**Input:** nums = [2,2], queries = [0,0] + +**Output:** [2,2] + +**Explanation:** + +`gcdPairs = [2]`. + +**Constraints:** + +* 2 <= n == nums.length <= 105 +* 1 <= nums[i] <= 5 * 104 +* 1 <= queries.length <= 105 +* `0 <= queries[i] < n * (n - 1) / 2` \ No newline at end of file diff --git a/src/test/java/g3301_3400/s3309_maximum_possible_number_by_binary_concatenation/SolutionTest.java b/src/test/java/g3301_3400/s3309_maximum_possible_number_by_binary_concatenation/SolutionTest.java new file mode 100644 index 000000000..bfd342d54 --- /dev/null +++ b/src/test/java/g3301_3400/s3309_maximum_possible_number_by_binary_concatenation/SolutionTest.java @@ -0,0 +1,18 @@ +package g3301_3400.s3309_maximum_possible_number_by_binary_concatenation; + +import static org.hamcrest.CoreMatchers.equalTo; +import static org.hamcrest.MatcherAssert.assertThat; + +import org.junit.jupiter.api.Test; + +class SolutionTest { + @Test + void maxGoodNumber() { + assertThat(new Solution().maxGoodNumber(new int[] {1, 2, 3}), equalTo(30)); + } + + @Test + void maxGoodNumber2() { + assertThat(new Solution().maxGoodNumber(new int[] {2, 8, 16}), equalTo(1296)); + } +} diff --git a/src/test/java/g3301_3400/s3310_remove_methods_from_project/SolutionTest.java b/src/test/java/g3301_3400/s3310_remove_methods_from_project/SolutionTest.java new file mode 100644 index 000000000..0b1fce403 --- /dev/null +++ b/src/test/java/g3301_3400/s3310_remove_methods_from_project/SolutionTest.java @@ -0,0 +1,30 @@ +package g3301_3400.s3310_remove_methods_from_project; + +import static org.hamcrest.CoreMatchers.equalTo; +import static org.hamcrest.MatcherAssert.assertThat; + +import java.util.List; +import org.junit.jupiter.api.Test; + +class SolutionTest { + @Test + void remainingMethods() { + assertThat( + new Solution().remainingMethods(4, 1, new int[][] {{1, 2}, {0, 1}, {3, 2}}), + equalTo(List.of(0, 1, 2, 3))); + } + + @Test + void remainingMethods2() { + assertThat( + new Solution().remainingMethods(5, 0, new int[][] {{1, 2}, {0, 2}, {0, 1}, {3, 4}}), + equalTo(List.of(3, 4))); + } + + @Test + void remainingMethods3() { + assertThat( + new Solution().remainingMethods(3, 2, new int[][] {{1, 2}, {0, 1}, {2, 0}}), + equalTo(List.of())); + } +} diff --git a/src/test/java/g3301_3400/s3311_construct_2d_grid_matching_graph_layout/SolutionTest.java b/src/test/java/g3301_3400/s3311_construct_2d_grid_matching_graph_layout/SolutionTest.java new file mode 100644 index 000000000..e5f2487f5 --- /dev/null +++ b/src/test/java/g3301_3400/s3311_construct_2d_grid_matching_graph_layout/SolutionTest.java @@ -0,0 +1,35 @@ +package g3301_3400.s3311_construct_2d_grid_matching_graph_layout; + +import static org.hamcrest.CoreMatchers.equalTo; +import static org.hamcrest.MatcherAssert.assertThat; + +import org.junit.jupiter.api.Test; + +class SolutionTest { + @Test + void constructGridLayout() { + assertThat( + new Solution().constructGridLayout(4, new int[][] {{0, 1}, {0, 2}, {1, 3}, {2, 3}}), + equalTo(new int[][] {{0, 2}, {1, 3}})); + } + + @Test + void constructGridLayout2() { + assertThat( + new Solution().constructGridLayout(5, new int[][] {{0, 1}, {1, 3}, {2, 3}, {2, 4}}), + equalTo(new int[][] {{0, 1, 3, 2, 4}})); + } + + @Test + void constructGridLayout3() { + assertThat( + new Solution() + .constructGridLayout( + 9, + new int[][] { + {0, 1}, {0, 4}, {0, 5}, {1, 7}, {2, 3}, {2, 4}, {2, 5}, {3, 6}, + {4, 6}, {4, 7}, {6, 8}, {7, 8} + }), + equalTo(new int[][] {{1, 0, 5}, {7, 4, 2}, {8, 6, 3}})); + } +} diff --git a/src/test/java/g3301_3400/s3312_sorted_gcd_pair_queries/SolutionTest.java b/src/test/java/g3301_3400/s3312_sorted_gcd_pair_queries/SolutionTest.java new file mode 100644 index 000000000..4d48c5935 --- /dev/null +++ b/src/test/java/g3301_3400/s3312_sorted_gcd_pair_queries/SolutionTest.java @@ -0,0 +1,22 @@ +package g3301_3400.s3312_sorted_gcd_pair_queries; + +import static org.hamcrest.CoreMatchers.equalTo; +import static org.hamcrest.MatcherAssert.assertThat; + +import org.junit.jupiter.api.Test; + +class SolutionTest { + @Test + void gcdValues() { + assertThat( + new Solution().gcdValues(new int[] {2, 3, 4}, new long[] {0L, 2L, 2L}), + equalTo(new int[] {1, 2, 2})); + } + + @Test + void gcdValues2() { + assertThat( + new Solution().gcdValues(new int[] {4, 4, 2, 1}, new long[] {5L, 3L, 1L, 0L}), + equalTo(new int[] {4, 2, 1, 1})); + } +}