diff --git a/src/main/kotlin/g3301_3400/s3309_maximum_possible_number_by_binary_concatenation/Solution.kt b/src/main/kotlin/g3301_3400/s3309_maximum_possible_number_by_binary_concatenation/Solution.kt new file mode 100644 index 000000000..6336c7f89 --- /dev/null +++ b/src/main/kotlin/g3301_3400/s3309_maximum_possible_number_by_binary_concatenation/Solution.kt @@ -0,0 +1,46 @@ +package g3301_3400.s3309_maximum_possible_number_by_binary_concatenation + +// #Medium #Array #Bit_Manipulation #Enumeration +// #2024_10_12_Time_182_ms_(73.47%)_Space_36.8_MB_(79.59%) + +class Solution { + private var result = "0" + + fun maxGoodNumber(nums: IntArray): Int { + val visited = BooleanArray(nums.size) + val sb = StringBuilder() + solve(nums, visited, 0, sb) + var score = 0 + var `val`: Int + for (c in result.toCharArray()) { + `val` = c.code - '0'.code + score *= 2 + score += `val` + } + return score + } + + private fun solve(nums: IntArray, visited: BooleanArray, pos: Int, sb: StringBuilder) { + if (pos == nums.size) { + val `val` = sb.toString() + if ((result.length == `val`.length && result.compareTo(`val`) < 0) || + `val`.length > result.length + ) { + result = `val` + } + return + } + var cur: String? + for (i in nums.indices) { + 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/kotlin/g3301_3400/s3309_maximum_possible_number_by_binary_concatenation/readme.md b/src/main/kotlin/g3301_3400/s3309_maximum_possible_number_by_binary_concatenation/readme.md new file mode 100644 index 000000000..4e6ecf1f1 --- /dev/null +++ b/src/main/kotlin/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/kotlin/g3301_3400/s3310_remove_methods_from_project/Solution.kt b/src/main/kotlin/g3301_3400/s3310_remove_methods_from_project/Solution.kt new file mode 100644 index 000000000..8711baa08 --- /dev/null +++ b/src/main/kotlin/g3301_3400/s3310_remove_methods_from_project/Solution.kt @@ -0,0 +1,73 @@ +package g3301_3400.s3310_remove_methods_from_project + +// #Medium #Depth_First_Search #Breadth_First_Search #Graph +// #2024_10_12_Time_1465_ms_(100.00%)_Space_201.7_MB_(14.81%) + +class Solution { + private lateinit var graph: Array + private lateinit var suspicious: BooleanArray + private lateinit var visited: BooleanArray + + fun remainingMethods(n: Int, k: Int, invocations: Array): List { + pack(invocations, n) + suspicious = BooleanArray(n) + visited = BooleanArray(n) + dfs(k, true) + visited.fill(false) + for (i in 0 until n) { + if (!suspicious[i] && dfs2(i)) { + visited.fill(false) + dfs(k, false) + break + } + } + val rst = ArrayList() + for (i in 0 until n) { + if (!suspicious[i]) { + rst.add(i) + } + } + return rst + } + + fun dfs(u: Int, sus: Boolean) { + if (visited[u]) { + return + } + visited[u] = true + suspicious[u] = sus + for (v in graph[u]!!) { + dfs(v, sus) + } + } + + fun dfs2(u: Int): Boolean { + if (suspicious[u]) { + return true + } + if (visited[u]) { + return false + } + visited[u] = true + for (v in graph[u]!!) { + if (dfs2(v)) { + return true + } + } + return false + } + + private fun pack(edges: Array, n: Int) { + val adj = IntArray(n) + for (edge in edges) { + adj[edge[0]]++ + } + graph = arrayOfNulls(n) + for (i in 0 until n) { + graph[i] = IntArray(adj[i]) + } + for (edge in edges) { + graph[edge[0]]!![--adj[edge[0]]] = edge[1] + } + } +} diff --git a/src/main/kotlin/g3301_3400/s3310_remove_methods_from_project/readme.md b/src/main/kotlin/g3301_3400/s3310_remove_methods_from_project/readme.md new file mode 100644 index 000000000..6a49b6989 --- /dev/null +++ b/src/main/kotlin/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/kotlin/g3301_3400/s3311_construct_2d_grid_matching_graph_layout/Solution.kt b/src/main/kotlin/g3301_3400/s3311_construct_2d_grid_matching_graph_layout/Solution.kt new file mode 100644 index 000000000..4cf0fc89a --- /dev/null +++ b/src/main/kotlin/g3301_3400/s3311_construct_2d_grid_matching_graph_layout/Solution.kt @@ -0,0 +1,135 @@ +package g3301_3400.s3311_construct_2d_grid_matching_graph_layout + +// #Hard #Array #Hash_Table #Matrix #Graph +// #2024_10_12_Time_1423_ms_(100.00%)_Space_113.1_MB_(100.00%) + +import kotlin.math.min + +class Solution { + fun constructGridLayout(n: Int, edges: Array): Array { + val cs = IntArray(n) + val als: Array> = Array>(n) { ArrayList() } + for (e in edges) { + cs[e[0]]++ + cs[e[1]]++ + als[e[0]].add(e[1]) + als[e[1]].add(e[0]) + } + var min = 4 + for (a in cs) { + min = min(min, a) + } + val seen = BooleanArray(n) + var res: Array + var st = 0 + for (i in 0 until n) { + if (cs[i] == min) { + st = i + break + } + } + if (min == 1) { + res = Array(1) { IntArray(n) } + for (i in 0 until n) { + res[0][i] = st + seen[st] = true + if (i + 1 < n) { + for (a in als[st]) { + if (!seen[a]) { + st = a + break + } + } + } + } + return res + } + var row2 = -1 + for (a in als[st]) { + if (cs[a] == min) { + row2 = a + break + } + } + if (row2 >= 0) { + return getInts2(n, st, row2, seen, als) + } + return getInts1(n, seen, st, als, cs) + } + + private fun getInts1( + n: Int, + seen: BooleanArray, + st: Int, + als: Array>, + cs: IntArray + ): Array { + var st = st + var res: Array + val al = ArrayList() + var f = true + seen[st] = true + al.add(st) + while (f) { + f = false + for (a in als[st]) { + if (!seen[a] && cs[a] <= 3) { + seen[a] = true + al.add(a) + if (cs[a] == 3) { + f = true + st = a + } + break + } + } + } + res = Array(n / al.size) { IntArray(al.size) } + for (i in res[0].indices) { + res[0][i] = al[i]!! + } + for (i in 1 until res.size) { + for (j in res[0].indices) { + for (a in als[res[i - 1][j]]) { + if (!seen[a]) { + res[i][j] = a + seen[a] = true + break + } + } + } + } + return res + } + + private fun getInts2( + n: Int, + st: Int, + row2: Int, + seen: BooleanArray, + als: Array> + ): Array { + var res: Array = Array(2) { IntArray(n / 2) } + res[0][0] = st + res[1][0] = row2 + seen[row2] = true + seen[st] = seen[row2] + for (i in 1 until res[0].size) { + for (a in als[res[0][i - 1]]) { + if (!seen[a]) { + res[0][i] = a + seen[a] = true + break + } + } + for (a in als[res[1][i - 1]]) { + if (!seen[a]) { + res[1][i] = a + seen[a] = true + break + } + } + } + return res + } +} diff --git a/src/main/kotlin/g3301_3400/s3311_construct_2d_grid_matching_graph_layout/readme.md b/src/main/kotlin/g3301_3400/s3311_construct_2d_grid_matching_graph_layout/readme.md new file mode 100644 index 000000000..a8ef87b54 --- /dev/null +++ b/src/main/kotlin/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/kotlin/g3301_3400/s3312_sorted_gcd_pair_queries/Solution.kt b/src/main/kotlin/g3301_3400/s3312_sorted_gcd_pair_queries/Solution.kt new file mode 100644 index 000000000..8e89cd9d3 --- /dev/null +++ b/src/main/kotlin/g3301_3400/s3312_sorted_gcd_pair_queries/Solution.kt @@ -0,0 +1,57 @@ +package g3301_3400.s3312_sorted_gcd_pair_queries + +// #Hard #Array #Hash_Table #Math #Binary_Search #Prefix_Sum #Counting #Number_Theory #Combinatorics +// #2024_10_12_Time_734_ms_(100.00%)_Space_75.3_MB_(50.00%) + +import kotlin.math.max + +class Solution { + fun gcdValues(nums: IntArray, queries: LongArray): IntArray { + var max = 1 + for (num in nums) { + max = max(max, num) + } + val gcdDp = LongArray(max + 1) + for (num in nums) { + gcdDp[num]++ + } + for (i in 1..max) { + var count: Long = 0 + var j = i + while (j <= max) { + count += gcdDp[j] + j = j + i + } + gcdDp[i] = ((count - 1) * count) / 2 + } + for (i in max downTo 1) { + var j = i + i + while (j <= max) { + gcdDp[i] -= gcdDp[j] + j = j + i + } + } + for (i in 1..max) { + gcdDp[i] += gcdDp[i - 1] + } + val result = IntArray(queries.size) + for (i in queries.indices) { + result[i] = binarySearch(max, gcdDp, queries[i] + 1) + } + return result + } + + private fun binarySearch(n: Int, arr: LongArray, `val`: Long): Int { + var l = 1 + var r = n + while (l < r) { + val mid = l + (r - l) / 2 + if (arr[mid] < `val`) { + l = mid + 1 + } else { + r = mid + } + } + return l + } +} diff --git a/src/main/kotlin/g3301_3400/s3312_sorted_gcd_pair_queries/readme.md b/src/main/kotlin/g3301_3400/s3312_sorted_gcd_pair_queries/readme.md new file mode 100644 index 000000000..64880b0bf --- /dev/null +++ b/src/main/kotlin/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/kotlin/g3301_3400/s3309_maximum_possible_number_by_binary_concatenation/SolutionTest.kt b/src/test/kotlin/g3301_3400/s3309_maximum_possible_number_by_binary_concatenation/SolutionTest.kt new file mode 100644 index 000000000..b741c0aac --- /dev/null +++ b/src/test/kotlin/g3301_3400/s3309_maximum_possible_number_by_binary_concatenation/SolutionTest.kt @@ -0,0 +1,17 @@ +package g3301_3400.s3309_maximum_possible_number_by_binary_concatenation + +import org.hamcrest.CoreMatchers.equalTo +import org.hamcrest.MatcherAssert.assertThat +import org.junit.jupiter.api.Test + +internal class SolutionTest { + @Test + fun maxGoodNumber() { + assertThat(Solution().maxGoodNumber(intArrayOf(1, 2, 3)), equalTo(30)) + } + + @Test + fun maxGoodNumber2() { + assertThat(Solution().maxGoodNumber(intArrayOf(2, 8, 16)), equalTo(1296)) + } +} diff --git a/src/test/kotlin/g3301_3400/s3310_remove_methods_from_project/SolutionTest.kt b/src/test/kotlin/g3301_3400/s3310_remove_methods_from_project/SolutionTest.kt new file mode 100644 index 000000000..ce5848447 --- /dev/null +++ b/src/test/kotlin/g3301_3400/s3310_remove_methods_from_project/SolutionTest.kt @@ -0,0 +1,35 @@ +package g3301_3400.s3310_remove_methods_from_project + +import org.hamcrest.CoreMatchers.equalTo +import org.hamcrest.MatcherAssert.assertThat +import org.junit.jupiter.api.Test + +internal class SolutionTest { + @Test + fun remainingMethods() { + assertThat>( + Solution().remainingMethods(4, 1, arrayOf(intArrayOf(1, 2), intArrayOf(0, 1), intArrayOf(3, 2))), + equalTo>(listOf(0, 1, 2, 3)) + ) + } + + @Test + fun remainingMethods2() { + assertThat>( + Solution().remainingMethods( + 5, + 0, + arrayOf(intArrayOf(1, 2), intArrayOf(0, 2), intArrayOf(0, 1), intArrayOf(3, 4)) + ), + equalTo>(listOf(3, 4)) + ) + } + + @Test + fun remainingMethods3() { + assertThat>( + Solution().remainingMethods(3, 2, arrayOf(intArrayOf(1, 2), intArrayOf(0, 1), intArrayOf(2, 0))), + equalTo>(listOf()) + ) + } +} diff --git a/src/test/kotlin/g3301_3400/s3311_construct_2d_grid_matching_graph_layout/SolutionTest.kt b/src/test/kotlin/g3301_3400/s3311_construct_2d_grid_matching_graph_layout/SolutionTest.kt new file mode 100644 index 000000000..9c604d243 --- /dev/null +++ b/src/test/kotlin/g3301_3400/s3311_construct_2d_grid_matching_graph_layout/SolutionTest.kt @@ -0,0 +1,60 @@ +package g3301_3400.s3311_construct_2d_grid_matching_graph_layout + +import org.hamcrest.CoreMatchers.equalTo +import org.hamcrest.MatcherAssert.assertThat +import org.junit.jupiter.api.Test + +internal class SolutionTest { + @Test + fun constructGridLayout() { + assertThat>( + Solution().constructGridLayout( + 4, + arrayOf(intArrayOf(0, 1), intArrayOf(0, 2), intArrayOf(1, 3), intArrayOf(2, 3)) + ), + equalTo>(arrayOf(intArrayOf(0, 2), intArrayOf(1, 3))) + ) + } + + @Test + fun constructGridLayout2() { + assertThat>( + Solution().constructGridLayout( + 5, + arrayOf(intArrayOf(0, 1), intArrayOf(1, 3), intArrayOf(2, 3), intArrayOf(2, 4)) + ), + equalTo>(arrayOf(intArrayOf(0, 1, 3, 2, 4))) + ) + } + + @Test + fun constructGridLayout3() { + assertThat>( + Solution() + .constructGridLayout( + 9, + arrayOf( + intArrayOf(0, 1), + intArrayOf(0, 4), + intArrayOf(0, 5), + intArrayOf(1, 7), + intArrayOf(2, 3), + intArrayOf(2, 4), + intArrayOf(2, 5), + intArrayOf(3, 6), + intArrayOf(4, 6), + intArrayOf(4, 7), + intArrayOf(6, 8), + intArrayOf(7, 8) + ) + ), + equalTo>( + arrayOf( + intArrayOf(1, 0, 5), + intArrayOf(7, 4, 2), + intArrayOf(8, 6, 3) + ) + ) + ) + } +} diff --git a/src/test/kotlin/g3301_3400/s3312_sorted_gcd_pair_queries/SolutionTest.kt b/src/test/kotlin/g3301_3400/s3312_sorted_gcd_pair_queries/SolutionTest.kt new file mode 100644 index 000000000..a1073118d --- /dev/null +++ b/src/test/kotlin/g3301_3400/s3312_sorted_gcd_pair_queries/SolutionTest.kt @@ -0,0 +1,23 @@ +package g3301_3400.s3312_sorted_gcd_pair_queries + +import org.hamcrest.CoreMatchers.equalTo +import org.hamcrest.MatcherAssert.assertThat +import org.junit.jupiter.api.Test + +internal class SolutionTest { + @Test + fun gcdValues() { + assertThat( + Solution().gcdValues(intArrayOf(2, 3, 4), longArrayOf(0L, 2L, 2L)), + equalTo(intArrayOf(1, 2, 2)) + ) + } + + @Test + fun gcdValues2() { + assertThat( + Solution().gcdValues(intArrayOf(4, 4, 2, 1), longArrayOf(5L, 3L, 1L, 0L)), + equalTo(intArrayOf(4, 2, 1, 1)) + ) + } +}