From 97ca0267e019b31d1b76d81dee6202cf7c2286b9 Mon Sep 17 00:00:00 2001 From: Valentyn Kolesnikov Date: Mon, 7 Jul 2025 11:54:49 +0300 Subject: [PATCH 1/4] Added tasks 3602-3609 --- .../Solution.kt | 39 ++++++ .../readme.md | 39 ++++++ .../Solution.kt | 30 +++++ .../readme.md | 77 ++++++++++++ .../Solution.kt | 112 ++++++++++++++++++ .../readme.md | 69 +++++++++++ .../Solution.kt | 94 +++++++++++++++ .../readme.md | 61 ++++++++++ .../s3606_coupon_code_validator/Solution.kt | 37 ++++++ .../s3606_coupon_code_validator/readme.md | 50 ++++++++ .../s3607_power_grid_maintenance/Solution.kt | 81 +++++++++++++ .../s3607_power_grid_maintenance/readme.md | 62 ++++++++++ .../Solution.kt | 63 ++++++++++ .../readme.md | 64 ++++++++++ .../Solution.kt | 49 ++++++++ .../readme.md | 60 ++++++++++ .../SolutionTest.kt | 17 +++ .../SolutionTest.kt | 39 ++++++ .../SolutionTest.kt | 65 ++++++++++ .../SolutionTest.kt | 22 ++++ .../SolutionTest.kt | 33 ++++++ .../SolutionTest.kt | 39 ++++++ .../SolutionTest.kt | 35 ++++++ .../SolutionTest.kt | 100 ++++++++++++++++ 24 files changed, 1337 insertions(+) create mode 100644 src/main/kotlin/g3601_3700/s3602_hexadecimal_and_hexatrigesimal_conversion/Solution.kt create mode 100644 src/main/kotlin/g3601_3700/s3602_hexadecimal_and_hexatrigesimal_conversion/readme.md create mode 100644 src/main/kotlin/g3601_3700/s3603_minimum_cost_path_with_alternating_directions_ii/Solution.kt create mode 100644 src/main/kotlin/g3601_3700/s3603_minimum_cost_path_with_alternating_directions_ii/readme.md create mode 100644 src/main/kotlin/g3601_3700/s3604_minimum_time_to_reach_destination_in_directed_graph/Solution.kt create mode 100644 src/main/kotlin/g3601_3700/s3604_minimum_time_to_reach_destination_in_directed_graph/readme.md create mode 100644 src/main/kotlin/g3601_3700/s3605_minimum_stability_factor_of_array/Solution.kt create mode 100644 src/main/kotlin/g3601_3700/s3605_minimum_stability_factor_of_array/readme.md create mode 100644 src/main/kotlin/g3601_3700/s3606_coupon_code_validator/Solution.kt create mode 100644 src/main/kotlin/g3601_3700/s3606_coupon_code_validator/readme.md create mode 100644 src/main/kotlin/g3601_3700/s3607_power_grid_maintenance/Solution.kt create mode 100644 src/main/kotlin/g3601_3700/s3607_power_grid_maintenance/readme.md create mode 100644 src/main/kotlin/g3601_3700/s3608_minimum_time_for_k_connected_components/Solution.kt create mode 100644 src/main/kotlin/g3601_3700/s3608_minimum_time_for_k_connected_components/readme.md create mode 100644 src/main/kotlin/g3601_3700/s3609_minimum_moves_to_reach_target_in_grid/Solution.kt create mode 100644 src/main/kotlin/g3601_3700/s3609_minimum_moves_to_reach_target_in_grid/readme.md create mode 100644 src/test/kotlin/g3601_3700/s3602_hexadecimal_and_hexatrigesimal_conversion/SolutionTest.kt create mode 100644 src/test/kotlin/g3601_3700/s3603_minimum_cost_path_with_alternating_directions_ii/SolutionTest.kt create mode 100644 src/test/kotlin/g3601_3700/s3604_minimum_time_to_reach_destination_in_directed_graph/SolutionTest.kt create mode 100644 src/test/kotlin/g3601_3700/s3605_minimum_stability_factor_of_array/SolutionTest.kt create mode 100644 src/test/kotlin/g3601_3700/s3606_coupon_code_validator/SolutionTest.kt create mode 100644 src/test/kotlin/g3601_3700/s3607_power_grid_maintenance/SolutionTest.kt create mode 100644 src/test/kotlin/g3601_3700/s3608_minimum_time_for_k_connected_components/SolutionTest.kt create mode 100644 src/test/kotlin/g3601_3700/s3609_minimum_moves_to_reach_target_in_grid/SolutionTest.kt diff --git a/src/main/kotlin/g3601_3700/s3602_hexadecimal_and_hexatrigesimal_conversion/Solution.kt b/src/main/kotlin/g3601_3700/s3602_hexadecimal_and_hexatrigesimal_conversion/Solution.kt new file mode 100644 index 00000000..9d0165aa --- /dev/null +++ b/src/main/kotlin/g3601_3700/s3602_hexadecimal_and_hexatrigesimal_conversion/Solution.kt @@ -0,0 +1,39 @@ +package g3601_3700.s3602_hexadecimal_and_hexatrigesimal_conversion + +// #Easy #2025_07_07_Time_2_ms_(100.00%)_Space_41.91_MB_(100.00%) + +class Solution { + fun concatHex36(n: Int): String { + var t = n * n + var k: Int + val st = StringBuilder() + var tmp = StringBuilder() + while (t > 0) { + k = t % 16 + t = t / 16 + if (k <= 9) { + tmp.append(('0'.code + k).toChar()) + } else { + tmp.append(('A'.code + (k - 10)).toChar()) + } + } + for (i in tmp.length - 1 downTo 0) { + st.append(tmp.get(i)) + } + tmp = StringBuilder() + t = n * n * n + while (t > 0) { + k = t % 36 + t = t / 36 + if (k <= 9) { + tmp.append(('0'.code + k).toChar()) + } else { + tmp.append(('A'.code + (k - 10)).toChar()) + } + } + for (i in tmp.length - 1 downTo 0) { + st.append(tmp.get(i)) + } + return st.toString() + } +} diff --git a/src/main/kotlin/g3601_3700/s3602_hexadecimal_and_hexatrigesimal_conversion/readme.md b/src/main/kotlin/g3601_3700/s3602_hexadecimal_and_hexatrigesimal_conversion/readme.md new file mode 100644 index 00000000..c08a5c4c --- /dev/null +++ b/src/main/kotlin/g3601_3700/s3602_hexadecimal_and_hexatrigesimal_conversion/readme.md @@ -0,0 +1,39 @@ +3602\. Hexadecimal and Hexatrigesimal Conversion + +Easy + +You are given an integer `n`. + +Return the concatenation of the **hexadecimal** representation of n2 and the **hexatrigesimal** representation of n3. + +A **hexadecimal** number is defined as a base-16 numeral system that uses the digits `0 – 9` and the uppercase letters `A - F` to represent values from 0 to 15. + +A **hexatrigesimal** number is defined as a base-36 numeral system that uses the digits `0 – 9` and the uppercase letters `A - Z` to represent values from 0 to 35. + +**Example 1:** + +**Input:** n = 13 + +**Output:** "A91P1" + +**Explanation:** + +* n2 = 13 * 13 = 169. In hexadecimal, it converts to `(10 * 16) + 9 = 169`, which corresponds to `"A9"`. +* n3 = 13 * 13 * 13 = 2197. In hexatrigesimal, it converts to (1 * 362) + (25 * 36) + 1 = 2197, which corresponds to `"1P1"`. +* Concatenating both results gives `"A9" + "1P1" = "A91P1"`. + +**Example 2:** + +**Input:** n = 36 + +**Output:** "5101000" + +**Explanation:** + +* n2 = 36 * 36 = 1296. In hexadecimal, it converts to (5 * 162) + (1 * 16) + 0 = 1296, which corresponds to `"510"`. +* n3 = 36 * 36 * 36 = 46656. In hexatrigesimal, it converts to (1 * 363) + (0 * 362) + (0 * 36) + 0 = 46656, which corresponds to `"1000"`. +* Concatenating both results gives `"510" + "1000" = "5101000"`. + +**Constraints:** + +* `1 <= n <= 1000` \ No newline at end of file diff --git a/src/main/kotlin/g3601_3700/s3603_minimum_cost_path_with_alternating_directions_ii/Solution.kt b/src/main/kotlin/g3601_3700/s3603_minimum_cost_path_with_alternating_directions_ii/Solution.kt new file mode 100644 index 00000000..90b8ab07 --- /dev/null +++ b/src/main/kotlin/g3601_3700/s3603_minimum_cost_path_with_alternating_directions_ii/Solution.kt @@ -0,0 +1,30 @@ +package g3601_3700.s3603_minimum_cost_path_with_alternating_directions_ii + +// #Medium #2025_07_07_Time_12_ms_(100.00%)_Space_84.57_MB_(100.00%) + +import kotlin.math.min + +class Solution { + fun minCost(m: Int, n: Int, waitCost: Array): Long { + val dp = LongArray(n) + dp[0] = 1L + for (j in 1..1 <= m, n <= 105 +* 2 <= m * n <= 105 +* `waitCost.length == m` +* `waitCost[0].length == n` +* 0 <= waitCost[i][j] <= 105 \ No newline at end of file diff --git a/src/main/kotlin/g3601_3700/s3604_minimum_time_to_reach_destination_in_directed_graph/Solution.kt b/src/main/kotlin/g3601_3700/s3604_minimum_time_to_reach_destination_in_directed_graph/Solution.kt new file mode 100644 index 00000000..6d166ae9 --- /dev/null +++ b/src/main/kotlin/g3601_3700/s3604_minimum_time_to_reach_destination_in_directed_graph/Solution.kt @@ -0,0 +1,112 @@ +package g3601_3700.s3604_minimum_time_to_reach_destination_in_directed_graph + +// #Medium #2025_07_07_Time_18_ms_(100.00%)_Space_132.61_MB_(100.00%) + +import kotlin.math.max + +class Solution { + fun minTime(n: Int, edges: Array): Int { + val head = IntArray(n) + val to = IntArray(edges.size) + val start = IntArray(edges.size) + val end = IntArray(edges.size) + val next = IntArray(edges.size) + head.fill(-1) + for (i in edges.indices) { + val u = edges[i][0] + to[i] = edges[i][1] + start[i] = edges[i][2] + end[i] = edges[i][3] + next[i] = head[u] + head[u] = i + } + val heap = IntArray(n) + val time = IntArray(n) + val pos = IntArray(n) + val visited = BooleanArray(n) + var size = 0 + for (i in 0.. 0) { + val u = heap[0] + heap[0] = heap[--size] + pos[heap[0]] = 0 + heapifyDown(heap, time, pos, size, 0) + if (visited[u]) { + continue + } + visited[u] = true + if (u == n - 1) { + return time[u] + } + var e = head[u] + while (e != -1) { + val v = to[e] + val t0 = time[u] + if (t0 > end[e]) { + e = next[e] + continue + } + val arrival = max(t0, start[e]) + 1 + if (arrival < time[v]) { + time[v] = arrival + if (pos[v] == -1) { + heap[size] = v + pos[v] = size + heapifyUp(heap, time, pos, size) + size++ + } else { + heapifyUp(heap, time, pos, pos[v]) + } + } + e = next[e] + } + } + return -1 + } + + private fun heapifyUp(heap: IntArray, time: IntArray, pos: IntArray, i: Int) { + var i = i + while (i > 0) { + val p = (i - 1) / 2 + if (time[heap[p]] <= time[heap[i]]) { + break + } + swap(heap, pos, i, p) + i = p + } + } + + private fun heapifyDown(heap: IntArray, time: IntArray, pos: IntArray, size: Int, i: Int) { + var i = i + while (2 * i + 1 < size) { + var j = 2 * i + 1 + if (j + 1 < size && time[heap[j + 1]] < time[heap[j]]) { + j++ + } + if (time[heap[i]] <= time[heap[j]]) { + break + } + swap(heap, pos, i, j) + i = j + } + } + + private fun swap(heap: IntArray, pos: IntArray, i: Int, j: Int) { + val tmp = heap[i] + heap[i] = heap[j] + heap[j] = tmp + pos[heap[i]] = i + pos[heap[j]] = j + } + + companion object { + private const val INF = Int.Companion.MAX_VALUE + } +} diff --git a/src/main/kotlin/g3601_3700/s3604_minimum_time_to_reach_destination_in_directed_graph/readme.md b/src/main/kotlin/g3601_3700/s3604_minimum_time_to_reach_destination_in_directed_graph/readme.md new file mode 100644 index 00000000..d947dade --- /dev/null +++ b/src/main/kotlin/g3601_3700/s3604_minimum_time_to_reach_destination_in_directed_graph/readme.md @@ -0,0 +1,69 @@ +3604\. Minimum Time to Reach Destination in Directed Graph + +Medium + +You are given an integer `n` and a **directed** graph with `n` nodes labeled from 0 to `n - 1`. This is represented by a 2D array `edges`, where edges[i] = [ui, vi, starti, endi] indicates an edge from node ui to vi that can **only** be used at any integer time `t` such that starti <= t <= endi. + +You start at node 0 at time 0. + +In one unit of time, you can either: + +* Wait at your current node without moving, or +* Travel along an outgoing edge from your current node if the current time `t` satisfies starti <= t <= endi. + +Return the **minimum** time required to reach node `n - 1`. If it is impossible, return `-1`. + +**Example 1:** + +**Input:** n = 3, edges = [[0,1,0,1],[1,2,2,5]] + +**Output:** 3 + +**Explanation:** + +![](https://assets.leetcode.com/uploads/2025/06/05/screenshot-2025-06-06-at-004535.png) + +The optimal path is: + +* At time `t = 0`, take the edge `(0 → 1)` which is available from 0 to 1. You arrive at node 1 at time `t = 1`, then wait until `t = 2`. +* At time ```t = `2` ```, take the edge `(1 → 2)` which is available from 2 to 5. You arrive at node 2 at time 3. + +Hence, the minimum time to reach node 2 is 3. + +**Example 2:** + +**Input:** n = 4, edges = [[0,1,0,3],[1,3,7,8],[0,2,1,5],[2,3,4,7]] + +**Output:** 5 + +**Explanation:** + +![](https://assets.leetcode.com/uploads/2025/06/05/screenshot-2025-06-06-at-004757.png) + +The optimal path is: + +* Wait at node 0 until time `t = 1`, then take the edge `(0 → 2)` which is available from 1 to 5. You arrive at node 2 at `t = 2`. +* Wait at node 2 until time `t = 4`, then take the edge `(2 → 3)` which is available from 4 to 7. You arrive at node 3 at `t = 5`. + +Hence, the minimum time to reach node 3 is 5. + +**Example 3:** + +**Input:** n = 3, edges = [[1,0,1,3],[1,2,3,5]] + +**Output:** \-1 + +**Explanation:** + +![](https://assets.leetcode.com/uploads/2025/06/05/screenshot-2025-06-06-at-004914.png) + +* Since there is no outgoing edge from node 0, it is impossible to reach node 2. Hence, the output is -1. + +**Constraints:** + +* 1 <= n <= 105 +* 0 <= edges.length <= 105 +* edges[i] == [ui, vi, starti, endi] +* 0 <= ui, vi <= n - 1 +* ui != vi +* 0 <= starti <= endi <= 109 \ No newline at end of file diff --git a/src/main/kotlin/g3601_3700/s3605_minimum_stability_factor_of_array/Solution.kt b/src/main/kotlin/g3601_3700/s3605_minimum_stability_factor_of_array/Solution.kt new file mode 100644 index 00000000..676de6f0 --- /dev/null +++ b/src/main/kotlin/g3601_3700/s3605_minimum_stability_factor_of_array/Solution.kt @@ -0,0 +1,94 @@ +package g3601_3700.s3605_minimum_stability_factor_of_array + +// #Hard #2025_07_07_Time_95_ms_(100.00%)_Space_77.89_MB_(100.00%) + +class Solution { + fun minStable(nums: IntArray, maxC: Int): Int { + val n = nums.size + var cnt = 0 + var idx = 0 + while (idx < n) { + cnt += if (nums[idx] >= 2) 1 else 0 + idx++ + } + if (cnt <= maxC) { + return 0 + } + val logs = IntArray(n + 1) + var maxLog = 0 + var temp = n + while (temp > 0) { + maxLog++ + temp = temp shr 1 + } + val table = Array(maxLog + 1) { IntArray(n) } + buildLogs(logs, n) + buildTable(table, nums, n, maxLog) + return binarySearch(nums, maxC, n, logs, table) + } + + private fun buildLogs(logs: IntArray, n: Int) { + var i = 2 + while (i <= n) { + logs[i] = logs[i shr 1] + 1 + i++ + } + } + + private fun buildTable(table: Array, nums: IntArray, n: Int, maxLog: Int) { + System.arraycopy(nums, 0, table[0], 0, n) + var level = 1 + while (level <= maxLog) { + var start = 0 + while (start + (1 shl level) <= n) { + table[level][start] = + gcd(table[level - 1][start], table[level - 1][start + (1 shl (level - 1))]) + start++ + } + level++ + } + } + + private fun binarySearch(nums: IntArray, maxC: Int, n: Int, logs: IntArray, table: Array): Int { + var left = 1 + var right = n + var result = n + while (left <= right) { + val mid = left + ((right - left) shr 1) + val valid = isValid(nums, maxC, mid, logs, table) + result = if (valid) mid else result + val newLeft = if (valid) left else mid + 1 + val newRight = if (valid) mid - 1 else right + left = newLeft + right = newRight + } + return result + } + + private fun isValid(arr: IntArray, limit: Int, segLen: Int, logs: IntArray, table: Array): Boolean { + val n = arr.size + val window = segLen + 1 + var cuts = 0 + var prevCut = -1 + var pos = 0 + while (pos + window - 1 < n && cuts <= limit) { + val rangeGcd = getRangeGcd(pos, pos + window - 1, logs, table) + if (rangeGcd >= 2) { + val shouldCut = prevCut < pos + cuts += if (shouldCut) 1 else 0 + prevCut = if (shouldCut) pos + window - 1 else prevCut + } + pos++ + } + return cuts <= limit + } + + private fun getRangeGcd(left: Int, right: Int, logs: IntArray, table: Array): Int { + val k = logs[right - left + 1] + return gcd(table[k][left], table[k][right - (1 shl k) + 1]) + } + + private fun gcd(a: Int, b: Int): Int { + return if (b == 0) a else gcd(b, a % b) + } +} diff --git a/src/main/kotlin/g3601_3700/s3605_minimum_stability_factor_of_array/readme.md b/src/main/kotlin/g3601_3700/s3605_minimum_stability_factor_of_array/readme.md new file mode 100644 index 00000000..e3d7712e --- /dev/null +++ b/src/main/kotlin/g3601_3700/s3605_minimum_stability_factor_of_array/readme.md @@ -0,0 +1,61 @@ +3605\. Minimum Stability Factor of Array + +Hard + +You are given an integer array `nums` and an integer `maxC`. + +A **subarray** is called **stable** if the _highest common factor (HCF)_ of all its elements is **greater than or equal to** 2. + +The **stability factor** of an array is defined as the length of its **longest** stable subarray. + +You may modify **at most** `maxC` elements of the array to any integer. + +Return the **minimum** possible stability factor of the array after at most `maxC` modifications. If no stable subarray remains, return 0. + +**Note:** + +* The **highest common factor (HCF)** of an array is the largest integer that evenly divides all the array elements. +* A **subarray** of length 1 is stable if its only element is greater than or equal to 2, since `HCF([x]) = x`. + +**Example 1:** + +**Input:** nums = [3,5,10], maxC = 1 + +**Output:** 1 + +**Explanation:** + +* The stable subarray `[5, 10]` has `HCF = 5`, which has a stability factor of 2. +* Since `maxC = 1`, one optimal strategy is to change `nums[1]` to `7`, resulting in `nums = [3, 7, 10]`. +* Now, no subarray of length greater than 1 has `HCF >= 2`. Thus, the minimum possible stability factor is 1. + +**Example 2:** + +**Input:** nums = [2,6,8], maxC = 2 + +**Output:** 1 + +**Explanation:** + +* The subarray `[2, 6, 8]` has `HCF = 2`, which has a stability factor of 3. +* Since `maxC = 2`, one optimal strategy is to change `nums[1]` to 3 and `nums[2]` to 5, resulting in `nums = [2, 3, 5]`. +* Now, no subarray of length greater than 1 has `HCF >= 2`. Thus, the minimum possible stability factor is 1. + +**Example 3:** + +**Input:** nums = [2,4,9,6], maxC = 1 + +**Output:** 2 + +**Explanation:** + +* The stable subarrays are: + * `[2, 4]` with `HCF = 2` and stability factor of 2. + * `[9, 6]` with `HCF = 3` and stability factor of 2. +* Since `maxC = 1`, the stability factor of 2 cannot be reduced due to two separate stable subarrays. Thus, the minimum possible stability factor is 2. + +**Constraints:** + +* 1 <= n == nums.length <= 105 +* 1 <= nums[i] <= 109 +* `0 <= maxC <= n` \ No newline at end of file diff --git a/src/main/kotlin/g3601_3700/s3606_coupon_code_validator/Solution.kt b/src/main/kotlin/g3601_3700/s3606_coupon_code_validator/Solution.kt new file mode 100644 index 00000000..0791174f --- /dev/null +++ b/src/main/kotlin/g3601_3700/s3606_coupon_code_validator/Solution.kt @@ -0,0 +1,37 @@ +package g3601_3700.s3606_coupon_code_validator + +// #Easy #2025_07_07_Time_32_ms_(100.00%)_Space_60.79_MB_(100.00%) + +class Solution { + fun validateCoupons(code: Array, businessLine: Array, isActive: BooleanArray): List { + val validBusinessLines = hashSetOf("electronics", "grocery", "pharmacy", "restaurant") + val filteredCoupons = mutableListOf>() + for (i in code.indices) { + if (!isActive[i]) { + continue + } + val currentBusinessLine = businessLine[i] + if (currentBusinessLine !in validBusinessLines) { + continue + } + val currentCode = code[i] + if (currentCode.isEmpty()) { + continue + } + + var isValidCodeChar = true + for (char in currentCode) { + if (!(char == '_' || char.isLetterOrDigit())) { + isValidCodeChar = false + break + } + } + + if (isValidCodeChar) { + filteredCoupons.add(Pair(currentCode, currentBusinessLine)) + } + } + filteredCoupons.sortWith(compareBy> { it.second }.thenBy { it.first }) + return filteredCoupons.map { it.first } + } +} diff --git a/src/main/kotlin/g3601_3700/s3606_coupon_code_validator/readme.md b/src/main/kotlin/g3601_3700/s3606_coupon_code_validator/readme.md new file mode 100644 index 00000000..7b346d64 --- /dev/null +++ b/src/main/kotlin/g3601_3700/s3606_coupon_code_validator/readme.md @@ -0,0 +1,50 @@ +3606\. Coupon Code Validator + +Easy + +You are given three arrays of length `n` that describe the properties of `n` coupons: `code`, `businessLine`, and `isActive`. The ith coupon has: + +* `code[i]`: a **string** representing the coupon identifier. +* `businessLine[i]`: a **string** denoting the business category of the coupon. +* `isActive[i]`: a **boolean** indicating whether the coupon is currently active. + +A coupon is considered **valid** if all of the following conditions hold: + +1. `code[i]` is non-empty and consists only of alphanumeric characters (a-z, A-Z, 0-9) and underscores (`_`). +2. `businessLine[i]` is one of the following four categories: `"electronics"`, `"grocery"`, `"pharmacy"`, `"restaurant"`. +3. `isActive[i]` is **true**. + +Return an array of the **codes** of all valid coupons, **sorted** first by their **businessLine** in the order: `"electronics"`, `"grocery"`, `"pharmacy", "restaurant"`, and then by **code** in lexicographical (ascending) order within each category. + +**Example 1:** + +**Input:** code = ["SAVE20","","PHARMA5","SAVE@20"], businessLine = ["restaurant","grocery","pharmacy","restaurant"], isActive = [true,true,true,true] + +**Output:** ["PHARMA5","SAVE20"] + +**Explanation:** + +* First coupon is valid. +* Second coupon has empty code (invalid). +* Third coupon is valid. +* Fourth coupon has special character `@` (invalid). + +**Example 2:** + +**Input:** code = ["GROCERY15","ELECTRONICS\_50","DISCOUNT10"], businessLine = ["grocery","electronics","invalid"], isActive = [false,true,true] + +**Output:** ["ELECTRONICS\_50"] + +**Explanation:** + +* First coupon is inactive (invalid). +* Second coupon is valid. +* Third coupon has invalid business line (invalid). + +**Constraints:** + +* `n == code.length == businessLine.length == isActive.length` +* `1 <= n <= 100` +* `0 <= code[i].length, businessLine[i].length <= 100` +* `code[i]` and `businessLine[i]` consist of printable ASCII characters. +* `isActive[i]` is either `true` or `false`. \ No newline at end of file diff --git a/src/main/kotlin/g3601_3700/s3607_power_grid_maintenance/Solution.kt b/src/main/kotlin/g3601_3700/s3607_power_grid_maintenance/Solution.kt new file mode 100644 index 00000000..46cc3ce1 --- /dev/null +++ b/src/main/kotlin/g3601_3700/s3607_power_grid_maintenance/Solution.kt @@ -0,0 +1,81 @@ +package g3601_3700.s3607_power_grid_maintenance + +// #Medium #2025_07_07_Time_91_ms_(100.00%)_Space_165.69_MB_(93.75%) + +import java.util.PriorityQueue + +class Solution { + private class UF(n: Int) { + val par: IntArray = IntArray(n) + val pq: Array> = Array(n) { PriorityQueue() } + val active: BooleanArray = BooleanArray(n) + + init { + for (i in 0 until n) { + active[i] = true + par[i] = i + pq[i].add(i) + } + } + + fun find(u: Int): Int { + if (par[u] == u) { + return u + } + par[u] = find(par[u]) + return par[u] + } + + fun union(u: Int, v: Int) { + val pu = find(u) + val pv = find(v) + if (pu == pv) { + return + } + if (pq[pu].size > pq[pv].size) { + while (pq[pv].isNotEmpty()) { + pq[pu].add(pq[pv].poll()) + } + par[pv] = pu // Should be pu, not par[pu] + } else { + while (pq[pu].isNotEmpty()) { + pq[pv].add(pq[pu].poll()) + } + par[pu] = pv // Should be pv, not par[pv] + } + } + + fun inactive(u: Int) { + active[u] = false + } + + fun check(u: Int): Int { + if (active[u]) { + return u + } + val pu = find(u) + while (pq[pu].isNotEmpty() && !active[pq[pu].peek()]) { + pq[pu].poll() + } + return if (pq[pu].isNotEmpty()) pq[pu].peek() else -2 + } + } + + fun processQueries(c: Int, connections: Array, queries: Array): IntArray { + val uf = UF(c) + for (con in connections) { + val u = con[0] + val v = con[1] + uf.union(u - 1, v - 1) + } + val res = mutableListOf() + for (q in queries) { + if (q[0] == 1) { + res.add(uf.check(q[1] - 1) + 1) + } else { + uf.inactive(q[1] - 1) + } + } + return res.toIntArray() + } +} diff --git a/src/main/kotlin/g3601_3700/s3607_power_grid_maintenance/readme.md b/src/main/kotlin/g3601_3700/s3607_power_grid_maintenance/readme.md new file mode 100644 index 00000000..f801ef4d --- /dev/null +++ b/src/main/kotlin/g3601_3700/s3607_power_grid_maintenance/readme.md @@ -0,0 +1,62 @@ +3607\. Power Grid Maintenance + +Medium + +You are given an integer `c` representing `c` power stations, each with a unique identifier `id` from 1 to `c` (1‑based indexing). + +These stations are interconnected via `n` **bidirectional** cables, represented by a 2D array `connections`, where each element connections[i] = [ui, vi] indicates a connection between station ui and station vi. Stations that are directly or indirectly connected form a **power grid**. + +Initially, **all** stations are online (operational). + +You are also given a 2D array `queries`, where each query is one of the following _two_ types: + +* `[1, x]`: A maintenance check is requested for station `x`. If station `x` is online, it resolves the check by itself. If station `x` is offline, the check is resolved by the operational station with the smallest `id` in the same **power grid** as `x`. If **no** **operational** station _exists_ in that grid, return -1. + +* `[2, x]`: Station `x` goes offline (i.e., it becomes non-operational). + + +Return an array of integers representing the results of each query of type `[1, x]` in the **order** they appear. + +**Note:** The power grid preserves its structure; an offline (non‑operational) node remains part of its grid and taking it offline does not alter connectivity. + +**Example 1:** + +**Input:** c = 5, connections = [[1,2],[2,3],[3,4],[4,5]], queries = [[1,3],[2,1],[1,1],[2,2],[1,2]] + +**Output:** [3,2,3] + +**Explanation:** + +![](https://assets.leetcode.com/uploads/2025/04/15/powergrid.jpg) + +* Initially, all stations `{1, 2, 3, 4, 5}` are online and form a single power grid. +* Query `[1,3]`: Station 3 is online, so the maintenance check is resolved by station 3. +* Query `[2,1]`: Station 1 goes offline. The remaining online stations are `{2, 3, 4, 5}`. +* Query `[1,1]`: Station 1 is offline, so the check is resolved by the operational station with the smallest `id` among `{2, 3, 4, 5}`, which is station 2. +* Query `[2,2]`: Station 2 goes offline. The remaining online stations are `{3, 4, 5}`. +* Query `[1,2]`: Station 2 is offline, so the check is resolved by the operational station with the smallest `id` among `{3, 4, 5}`, which is station 3. + +**Example 2:** + +**Input:** c = 3, connections = [], queries = [[1,1],[2,1],[1,1]] + +**Output:** [1,-1] + +**Explanation:** + +* There are no connections, so each station is its own isolated grid. +* Query `[1,1]`: Station 1 is online in its isolated grid, so the maintenance check is resolved by station 1. +* Query `[2,1]`: Station 1 goes offline. +* Query `[1,1]`: Station 1 is offline and there are no other stations in its grid, so the result is -1. + +**Constraints:** + +* 1 <= c <= 105 +* 0 <= n == connections.length <= min(105, c * (c - 1) / 2) +* `connections[i].length == 2` +* 1 <= ui, vi <= c +* ui != vi +* 1 <= queries.length <= 2 * 105 +* `queries[i].length == 2` +* `queries[i][0]` is either 1 or 2. +* `1 <= queries[i][1] <= c` \ No newline at end of file diff --git a/src/main/kotlin/g3601_3700/s3608_minimum_time_for_k_connected_components/Solution.kt b/src/main/kotlin/g3601_3700/s3608_minimum_time_for_k_connected_components/Solution.kt new file mode 100644 index 00000000..1c36d592 --- /dev/null +++ b/src/main/kotlin/g3601_3700/s3608_minimum_time_for_k_connected_components/Solution.kt @@ -0,0 +1,63 @@ +package g3601_3700.s3608_minimum_time_for_k_connected_components + +// #Medium #2025_07_07_Time_31_ms_(100.00%)_Space_114.78_MB_(100.00%) + +class Solution { + fun minTime(n: Int, edges: Array, k: Int): Int { + var maxTime = 0 + for (e in edges) { + if (e[2] > maxTime) { + maxTime = e[2] + } + } + var lo = 0 + var hi = maxTime + var ans = maxTime + while (lo <= hi) { + val mid = lo + (hi - lo) / 2 + if (countComponents(n, edges, mid) >= k) { + ans = mid + hi = mid - 1 + } else { + lo = mid + 1 + } + } + return ans + } + + private fun countComponents(n: Int, edges: Array, t: Int): Int { + val parent = IntArray(n) + val size = IntArray(n) + for (i in 0.. t) { + var u = find(parent, e[0]) + var v = find(parent, e[1]) + if (u != v) { + if (size[u] < size[v]) { + val tmp = u + u = v + v = tmp + } + parent[v] = u + size[u] += size[v] + comps-- + } + } + } + return comps + } + + private fun find(parent: IntArray, x: Int): Int { + var x = x + while (parent[x] != x) { + parent[x] = parent[parent[x]] + x = parent[x] + } + return x + } +} diff --git a/src/main/kotlin/g3601_3700/s3608_minimum_time_for_k_connected_components/readme.md b/src/main/kotlin/g3601_3700/s3608_minimum_time_for_k_connected_components/readme.md new file mode 100644 index 00000000..bee4301f --- /dev/null +++ b/src/main/kotlin/g3601_3700/s3608_minimum_time_for_k_connected_components/readme.md @@ -0,0 +1,64 @@ +3608\. Minimum Time for K Connected Components + +Medium + +You are given an integer `n` and an undirected graph with `n` nodes labeled from 0 to `n - 1`. This is represented by a 2D array `edges`, where edges[i] = [ui, vi, timei] indicates an undirected edge between nodes ui and vi that can be removed at timei. + +You are also given an integer `k`. + +Initially, the graph may be connected or disconnected. Your task is to find the **minimum** time `t` such that after removing all edges with `time <= t`, the graph contains **at least** `k` connected components. + +Return the **minimum** time `t`. + +A **connected component** is a subgraph of a graph in which there exists a path between any two vertices, and no vertex of the subgraph shares an edge with a vertex outside of the subgraph. + +**Example 1:** + +**Input:** n = 2, edges = [[0,1,3]], k = 2 + +**Output:** 3 + +**Explanation:** + +![](https://assets.leetcode.com/uploads/2025/05/31/screenshot-2025-06-01-at-022724.png) + +* Initially, there is one connected component `{0, 1}`. +* At `time = 1` or `2`, the graph remains unchanged. +* At `time = 3`, edge `[0, 1]` is removed, resulting in `k = 2` connected components `{0}`, `{1}`. Thus, the answer is 3. + +**Example 2:** + +**Input:** n = 3, edges = [[0,1,2],[1,2,4]], k = 3 + +**Output:** 4 + +**Explanation:** + +![](https://assets.leetcode.com/uploads/2025/05/31/screenshot-2025-06-01-at-022812.png) + +* Initially, there is one connected component `{0, 1, 2}`. +* At `time = 2`, edge `[0, 1]` is removed, resulting in two connected components `{0}`, `{1, 2}`. +* At `time = 4`, edge `[1, 2]` is removed, resulting in `k = 3` connected components `{0}`, `{1}`, `{2}`. Thus, the answer is 4. + +**Example 3:** + +**Input:** n = 3, edges = [[0,2,5]], k = 2 + +**Output:** 0 + +**Explanation:** + +![](https://assets.leetcode.com/uploads/2025/05/31/screenshot-2025-06-01-at-022930.png) + +* Since there are already `k = 2` disconnected components `{1}`, `{0, 2}`, no edge removal is needed. Thus, the answer is 0. + +**Constraints:** + +* 1 <= n <= 105 +* 0 <= edges.length <= 105 +* edges[i] = [ui, vi, timei] +* 0 <= ui, vi < n +* ui != vi +* 1 <= timei <= 109 +* `1 <= k <= n` +* There are no duplicate edges. \ No newline at end of file diff --git a/src/main/kotlin/g3601_3700/s3609_minimum_moves_to_reach_target_in_grid/Solution.kt b/src/main/kotlin/g3601_3700/s3609_minimum_moves_to_reach_target_in_grid/Solution.kt new file mode 100644 index 00000000..a344bb1d --- /dev/null +++ b/src/main/kotlin/g3601_3700/s3609_minimum_moves_to_reach_target_in_grid/Solution.kt @@ -0,0 +1,49 @@ +package g3601_3700.s3609_minimum_moves_to_reach_target_in_grid + +// #Hard #2025_07_07_Time_1_ms_(100.00%)_Space_40.67_MB_(100.00%) + +class Solution { + fun minMoves(sx: Int, sy: Int, tx: Int, ty: Int): Int { + var tx = tx + var ty = ty + if (sx == 0 && sy == 0) { + return if (tx == 0 && ty == 0) 0 else -1 + } + + var res = 0 + while (sx != tx || sy != ty) { + if (sx > tx || sy > ty) { + return -1 + } + res++ + if (tx > ty) { + if (tx > ty * 2) { + if (tx % 2 != 0) { + return -1 + } + tx /= 2 + } else { + tx -= ty + } + } else if (tx < ty) { + if (ty > tx * 2) { + if (ty % 2 != 0) { + return -1 + } + ty /= 2 + } else { + ty -= tx + } + } else { + if (sx == 0) { + tx = 0 + } else if (sy == 0) { + ty = 0 + } else { + return -1 + } + } + } + return res + } +} diff --git a/src/main/kotlin/g3601_3700/s3609_minimum_moves_to_reach_target_in_grid/readme.md b/src/main/kotlin/g3601_3700/s3609_minimum_moves_to_reach_target_in_grid/readme.md new file mode 100644 index 00000000..1f662239 --- /dev/null +++ b/src/main/kotlin/g3601_3700/s3609_minimum_moves_to_reach_target_in_grid/readme.md @@ -0,0 +1,60 @@ +3609\. Minimum Moves to Reach Target in Grid + +Hard + +You are given four integers `sx`, `sy`, `tx`, and `ty`, representing two points `(sx, sy)` and `(tx, ty)` on an infinitely large 2D grid. + +You start at `(sx, sy)`. + +At any point `(x, y)`, define `m = max(x, y)`. You can either: + +* Move to `(x + m, y)`, or +* Move to `(x, y + m)`. + +Return the **minimum** number of moves required to reach `(tx, ty)`. If it is impossible to reach the target, return -1. + +**Example 1:** + +**Input:** sx = 1, sy = 2, tx = 5, ty = 4 + +**Output:** 2 + +**Explanation:** + +The optimal path is: + +* Move 1: `max(1, 2) = 2`. Increase the y-coordinate by 2, moving from `(1, 2)` to `(1, 2 + 2) = (1, 4)`. +* Move 2: `max(1, 4) = 4`. Increase the x-coordinate by 4, moving from `(1, 4)` to `(1 + 4, 4) = (5, 4)`. + +Thus, the minimum number of moves to reach `(5, 4)` is 2. + +**Example 2:** + +**Input:** sx = 0, sy = 1, tx = 2, ty = 3 + +**Output:** 3 + +**Explanation:** + +The optimal path is: + +* Move 1: `max(0, 1) = 1`. Increase the x-coordinate by 1, moving from `(0, 1)` to `(0 + 1, 1) = (1, 1)`. +* Move 2: `max(1, 1) = 1`. Increase the x-coordinate by 1, moving from `(1, 1)` to `(1 + 1, 1) = (2, 1)`. +* Move 3: `max(2, 1) = 2`. Increase the y-coordinate by 2, moving from `(2, 1)` to `(2, 1 + 2) = (2, 3)`. + +Thus, the minimum number of moves to reach `(2, 3)` is 3. + +**Example 3:** + +**Input:** sx = 1, sy = 1, tx = 2, ty = 2 + +**Output:** \-1 + +**Explanation:** + +* It is impossible to reach `(2, 2)` from `(1, 1)` using the allowed moves. Thus, the answer is -1. + +**Constraints:** + +* 0 <= sx <= tx <= 109 +* 0 <= sy <= ty <= 109 \ No newline at end of file diff --git a/src/test/kotlin/g3601_3700/s3602_hexadecimal_and_hexatrigesimal_conversion/SolutionTest.kt b/src/test/kotlin/g3601_3700/s3602_hexadecimal_and_hexatrigesimal_conversion/SolutionTest.kt new file mode 100644 index 00000000..6acf8382 --- /dev/null +++ b/src/test/kotlin/g3601_3700/s3602_hexadecimal_and_hexatrigesimal_conversion/SolutionTest.kt @@ -0,0 +1,17 @@ +package g3601_3700.s3602_hexadecimal_and_hexatrigesimal_conversion + +import org.hamcrest.CoreMatchers.equalTo +import org.hamcrest.MatcherAssert.assertThat +import org.junit.jupiter.api.Test + +internal class SolutionTest { + @Test + fun concatHex36() { + assertThat(Solution().concatHex36(13), equalTo("A91P1")) + } + + @Test + fun concatHex362() { + assertThat(Solution().concatHex36(36), equalTo("5101000")) + } +} diff --git a/src/test/kotlin/g3601_3700/s3603_minimum_cost_path_with_alternating_directions_ii/SolutionTest.kt b/src/test/kotlin/g3601_3700/s3603_minimum_cost_path_with_alternating_directions_ii/SolutionTest.kt new file mode 100644 index 00000000..aa936b64 --- /dev/null +++ b/src/test/kotlin/g3601_3700/s3603_minimum_cost_path_with_alternating_directions_ii/SolutionTest.kt @@ -0,0 +1,39 @@ +package g3601_3700.s3603_minimum_cost_path_with_alternating_directions_ii + +import org.hamcrest.CoreMatchers.equalTo +import org.hamcrest.MatcherAssert.assertThat +import org.junit.jupiter.api.Test + +internal class SolutionTest { + @Test + fun minCost() { + assertThat( + Solution().minCost(1, 2, arrayOf(intArrayOf(1, 2))), + equalTo(3L), + ) + } + + @Test + fun minCost2() { + assertThat( + Solution().minCost( + 2, + 2, + arrayOf(intArrayOf(3, 5), intArrayOf(2, 4)), + ), + equalTo(9L), + ) + } + + @Test + fun minCost3() { + assertThat( + Solution().minCost( + 2, + 3, + arrayOf(intArrayOf(6, 1, 4), intArrayOf(3, 2, 5)), + ), + equalTo(16L), + ) + } +} diff --git a/src/test/kotlin/g3601_3700/s3604_minimum_time_to_reach_destination_in_directed_graph/SolutionTest.kt b/src/test/kotlin/g3601_3700/s3604_minimum_time_to_reach_destination_in_directed_graph/SolutionTest.kt new file mode 100644 index 00000000..e2be01b3 --- /dev/null +++ b/src/test/kotlin/g3601_3700/s3604_minimum_time_to_reach_destination_in_directed_graph/SolutionTest.kt @@ -0,0 +1,65 @@ +package g3601_3700.s3604_minimum_time_to_reach_destination_in_directed_graph + +import org.hamcrest.CoreMatchers.equalTo +import org.hamcrest.MatcherAssert.assertThat +import org.junit.jupiter.api.Test + +internal class SolutionTest { + @Test + fun minTime() { + assertThat( + Solution().minTime( + 3, + arrayOf(intArrayOf(0, 1, 0, 1), intArrayOf(1, 2, 2, 5)), + ), + equalTo(3), + ) + } + + @Test + fun minTime2() { + assertThat( + Solution() + .minTime( + 4, + arrayOf( + intArrayOf(0, 1, 0, 3), + intArrayOf(1, 3, 7, 8), + intArrayOf(0, 2, 1, 5), + intArrayOf(2, 3, 4, 7), + ), + ), + equalTo(5), + ) + } + + @Test + fun minTime3() { + assertThat( + Solution().minTime(3, arrayOf(intArrayOf(1, 0, 1, 3), intArrayOf(1, 2, 3, 5))), + equalTo(-1), + ) + } + + @Test + fun minTest4() { + assertThat( + Solution() + .minTime( + 5, + arrayOf( + intArrayOf(1, 3, 17, 18), + intArrayOf(1, 3, 0, 7), + intArrayOf(0, 1, 0, 3), + intArrayOf(3, 2, 1, 20), + intArrayOf(1, 2, 25, 25), + intArrayOf(0, 3, 13, 14), + intArrayOf(1, 0, 11, 15), + intArrayOf(0, 4, 19, 21), + intArrayOf(2, 0, 4, 20), + ), + ), + equalTo(20), + ) + } +} diff --git a/src/test/kotlin/g3601_3700/s3605_minimum_stability_factor_of_array/SolutionTest.kt b/src/test/kotlin/g3601_3700/s3605_minimum_stability_factor_of_array/SolutionTest.kt new file mode 100644 index 00000000..706dfcbe --- /dev/null +++ b/src/test/kotlin/g3601_3700/s3605_minimum_stability_factor_of_array/SolutionTest.kt @@ -0,0 +1,22 @@ +package g3601_3700.s3605_minimum_stability_factor_of_array + +import org.hamcrest.CoreMatchers.equalTo +import org.hamcrest.MatcherAssert.assertThat +import org.junit.jupiter.api.Test + +internal class SolutionTest { + @Test + fun minStable() { + assertThat(Solution().minStable(intArrayOf(3, 5, 10), 1), equalTo(1)) + } + + @Test + fun minStable2() { + assertThat(Solution().minStable(intArrayOf(2, 6, 8), 2), equalTo(1)) + } + + @Test + fun minStable3() { + assertThat(Solution().minStable(intArrayOf(2, 4, 9, 6), 1), equalTo(2)) + } +} diff --git a/src/test/kotlin/g3601_3700/s3606_coupon_code_validator/SolutionTest.kt b/src/test/kotlin/g3601_3700/s3606_coupon_code_validator/SolutionTest.kt new file mode 100644 index 00000000..7ce8fb99 --- /dev/null +++ b/src/test/kotlin/g3601_3700/s3606_coupon_code_validator/SolutionTest.kt @@ -0,0 +1,33 @@ +package g3601_3700.s3606_coupon_code_validator + +import org.hamcrest.CoreMatchers.equalTo +import org.hamcrest.MatcherAssert.assertThat +import org.junit.jupiter.api.Test + +internal class SolutionTest { + @Test + fun validateCoupons() { + assertThat>( + Solution() + .validateCoupons( + arrayOf("SAVE20", "", "PHARMA5", "SAVE@20"), + arrayOf("restaurant", "grocery", "pharmacy", "restaurant"), + booleanArrayOf(true, true, true, true), + ), + equalTo>(mutableListOf("PHARMA5", "SAVE20")), + ) + } + + @Test + fun validateCoupons2() { + assertThat>( + Solution() + .validateCoupons( + arrayOf("GROCERY15", "ELECTRONICS_50", "DISCOUNT10"), + arrayOf("grocery", "electronics", "invalid"), + booleanArrayOf(false, true, true), + ), + equalTo>(mutableListOf("ELECTRONICS_50")), + ) + } +} diff --git a/src/test/kotlin/g3601_3700/s3607_power_grid_maintenance/SolutionTest.kt b/src/test/kotlin/g3601_3700/s3607_power_grid_maintenance/SolutionTest.kt new file mode 100644 index 00000000..9eb5185a --- /dev/null +++ b/src/test/kotlin/g3601_3700/s3607_power_grid_maintenance/SolutionTest.kt @@ -0,0 +1,39 @@ +package g3601_3700.s3607_power_grid_maintenance + +import org.hamcrest.CoreMatchers.equalTo +import org.hamcrest.MatcherAssert.assertThat +import org.junit.jupiter.api.Test + +internal class SolutionTest { + @Test + fun processQueries() { + assertThat( + Solution() + .processQueries( + 5, + arrayOf(intArrayOf(1, 2), intArrayOf(2, 3), intArrayOf(3, 4), intArrayOf(4, 5)), + arrayOf( + intArrayOf(1, 3), + intArrayOf(2, 1), + intArrayOf(1, 1), + intArrayOf(2, 2), + intArrayOf(1, 2), + ), + ), + equalTo(intArrayOf(3, 2, 3)), + ) + } + + @Test + fun processQueries2() { + assertThat( + Solution() + .processQueries( + 3, + arrayOf(), + arrayOf(intArrayOf(1, 1), intArrayOf(2, 1), intArrayOf(1, 1)), + ), + equalTo(intArrayOf(1, -1)), + ) + } +} diff --git a/src/test/kotlin/g3601_3700/s3608_minimum_time_for_k_connected_components/SolutionTest.kt b/src/test/kotlin/g3601_3700/s3608_minimum_time_for_k_connected_components/SolutionTest.kt new file mode 100644 index 00000000..9c549b6b --- /dev/null +++ b/src/test/kotlin/g3601_3700/s3608_minimum_time_for_k_connected_components/SolutionTest.kt @@ -0,0 +1,35 @@ +package g3601_3700.s3608_minimum_time_for_k_connected_components + +import org.hamcrest.CoreMatchers.equalTo +import org.hamcrest.MatcherAssert.assertThat +import org.junit.jupiter.api.Test + +internal class SolutionTest { + @Test + fun minTime() { + assertThat( + Solution().minTime(2, arrayOf(intArrayOf(0, 1, 3)), 2), + equalTo(3), + ) + } + + @Test + fun minTime2() { + assertThat( + Solution().minTime( + 3, + arrayOf(intArrayOf(0, 1, 2), intArrayOf(1, 2, 4)), + 3, + ), + equalTo(4), + ) + } + + @Test + fun minTime3() { + assertThat( + Solution().minTime(3, arrayOf(intArrayOf(0, 2, 5)), 2), + equalTo(0), + ) + } +} diff --git a/src/test/kotlin/g3601_3700/s3609_minimum_moves_to_reach_target_in_grid/SolutionTest.kt b/src/test/kotlin/g3601_3700/s3609_minimum_moves_to_reach_target_in_grid/SolutionTest.kt new file mode 100644 index 00000000..7785172a --- /dev/null +++ b/src/test/kotlin/g3601_3700/s3609_minimum_moves_to_reach_target_in_grid/SolutionTest.kt @@ -0,0 +1,100 @@ +package g3601_3700.s3609_minimum_moves_to_reach_target_in_grid + +import org.hamcrest.CoreMatchers.equalTo +import org.hamcrest.MatcherAssert.assertThat +import org.junit.jupiter.api.Test + +internal class SolutionTest { + @Test + fun minMoves() { + assertThat(Solution().minMoves(1, 2, 5, 4), equalTo(2)) + } + + @Test + fun minMoves2() { + assertThat(Solution().minMoves(0, 1, 2, 3), equalTo(3)) + } + + @Test + fun minMoves3() { + assertThat(Solution().minMoves(1, 1, 2, 2), equalTo(-1)) + } + + @Test + fun minMoves4() { + assertThat(Solution().minMoves(0, 0, 0, 0), equalTo(0)) + } + + @Test + fun minMoves5() { + assertThat(Solution().minMoves(0, 0, 1, 0), equalTo(-1)) + assertThat(Solution().minMoves(0, 0, 0, 1), equalTo(-1)) + } + + @Test + fun minMoves6() { + assertThat(Solution().minMoves(2, 0, 1, 0), equalTo(-1)) + } + + @Test + fun minMoves7() { + assertThat(Solution().minMoves(0, 2, 0, 1), equalTo(-1)) + } + + @Test + fun minMoves8() { + assertThat(Solution().minMoves(1, 1, 9, 4), equalTo(-1)) + } + + @Test + fun minMoves9() { + val result = Solution().minMoves(1, 1, 8, 3) + assertThat(result, equalTo(-1)) + } + + @Test + fun minMoves10() { + val result = Solution().minMoves(1, 1, 6, 4) + assertThat(result, equalTo(-1)) + } + + @Test + fun minMoves11() { + assertThat(Solution().minMoves(1, 1, 4, 9), equalTo(-1)) + } + + @Test + fun minMoves12() { + val result = Solution().minMoves(1, 1, 3, 8) + assertThat(result, equalTo(-1)) + } + + @Test + fun minMoves13() { + val result = Solution().minMoves(1, 1, 4, 6) + assertThat(result, equalTo(-1)) + } + + @Test + fun minMoves14() { + val result = Solution().minMoves(0, 2, 5, 5) + assertThat(result, equalTo(-1)) + } + + @Test + fun minMoves15() { + val result = Solution().minMoves(2, 0, 5, 5) + assertThat(result, equalTo(-1)) + } + + @Test + fun minMoves16() { + assertThat(Solution().minMoves(2, 2, 5, 5), equalTo(-1)) + } + + @Test + fun minMoves17() { + val result = Solution().minMoves(1, 1, 5, 2) + assertThat(result, equalTo(-1)) + } +} From ba883797fc4def95beeac7746a36cd7a1d703c9b Mon Sep 17 00:00:00 2001 From: Valentyn Kolesnikov Date: Mon, 7 Jul 2025 12:09:20 +0300 Subject: [PATCH 2/4] Fixed sonar --- .../Solution.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/kotlin/g3601_3700/s3602_hexadecimal_and_hexatrigesimal_conversion/Solution.kt b/src/main/kotlin/g3601_3700/s3602_hexadecimal_and_hexatrigesimal_conversion/Solution.kt index 9d0165aa..ecba8cae 100644 --- a/src/main/kotlin/g3601_3700/s3602_hexadecimal_and_hexatrigesimal_conversion/Solution.kt +++ b/src/main/kotlin/g3601_3700/s3602_hexadecimal_and_hexatrigesimal_conversion/Solution.kt @@ -18,7 +18,7 @@ class Solution { } } for (i in tmp.length - 1 downTo 0) { - st.append(tmp.get(i)) + st.append(tmp[i]) } tmp = StringBuilder() t = n * n * n @@ -32,7 +32,7 @@ class Solution { } } for (i in tmp.length - 1 downTo 0) { - st.append(tmp.get(i)) + st.append(tmp[i]) } return st.toString() } From 1b76ef8f70e319a37f0b107294158cf7941e66ef Mon Sep 17 00:00:00 2001 From: Valentyn Kolesnikov Date: Tue, 8 Jul 2025 09:59:07 +0300 Subject: [PATCH 3/4] Updated tags --- .../Solution.kt | 2 +- .../Solution.kt | 3 ++- .../Solution.kt | 3 ++- .../s3605_minimum_stability_factor_of_array/Solution.kt | 3 ++- .../kotlin/g3601_3700/s3606_coupon_code_validator/Solution.kt | 3 ++- .../kotlin/g3601_3700/s3607_power_grid_maintenance/Solution.kt | 3 ++- .../s3608_minimum_time_for_k_connected_components/Solution.kt | 3 ++- .../s3609_minimum_moves_to_reach_target_in_grid/Solution.kt | 2 +- 8 files changed, 14 insertions(+), 8 deletions(-) diff --git a/src/main/kotlin/g3601_3700/s3602_hexadecimal_and_hexatrigesimal_conversion/Solution.kt b/src/main/kotlin/g3601_3700/s3602_hexadecimal_and_hexatrigesimal_conversion/Solution.kt index ecba8cae..caad0311 100644 --- a/src/main/kotlin/g3601_3700/s3602_hexadecimal_and_hexatrigesimal_conversion/Solution.kt +++ b/src/main/kotlin/g3601_3700/s3602_hexadecimal_and_hexatrigesimal_conversion/Solution.kt @@ -1,6 +1,6 @@ package g3601_3700.s3602_hexadecimal_and_hexatrigesimal_conversion -// #Easy #2025_07_07_Time_2_ms_(100.00%)_Space_41.91_MB_(100.00%) +// #Easy #String #Math #2025_07_07_Time_2_ms_(100.00%)_Space_41.91_MB_(100.00%) class Solution { fun concatHex36(n: Int): String { diff --git a/src/main/kotlin/g3601_3700/s3603_minimum_cost_path_with_alternating_directions_ii/Solution.kt b/src/main/kotlin/g3601_3700/s3603_minimum_cost_path_with_alternating_directions_ii/Solution.kt index 90b8ab07..83482658 100644 --- a/src/main/kotlin/g3601_3700/s3603_minimum_cost_path_with_alternating_directions_ii/Solution.kt +++ b/src/main/kotlin/g3601_3700/s3603_minimum_cost_path_with_alternating_directions_ii/Solution.kt @@ -1,6 +1,7 @@ package g3601_3700.s3603_minimum_cost_path_with_alternating_directions_ii -// #Medium #2025_07_07_Time_12_ms_(100.00%)_Space_84.57_MB_(100.00%) +// #Medium #Array #Dynamic_Programming #Matrix +// #2025_07_07_Time_12_ms_(100.00%)_Space_84.57_MB_(100.00%) import kotlin.math.min diff --git a/src/main/kotlin/g3601_3700/s3604_minimum_time_to_reach_destination_in_directed_graph/Solution.kt b/src/main/kotlin/g3601_3700/s3604_minimum_time_to_reach_destination_in_directed_graph/Solution.kt index 6d166ae9..9ecd986b 100644 --- a/src/main/kotlin/g3601_3700/s3604_minimum_time_to_reach_destination_in_directed_graph/Solution.kt +++ b/src/main/kotlin/g3601_3700/s3604_minimum_time_to_reach_destination_in_directed_graph/Solution.kt @@ -1,6 +1,7 @@ package g3601_3700.s3604_minimum_time_to_reach_destination_in_directed_graph -// #Medium #2025_07_07_Time_18_ms_(100.00%)_Space_132.61_MB_(100.00%) +// #Medium #Heap_Priority_Queue #Graph #Shortest_Path +// #2025_07_07_Time_18_ms_(100.00%)_Space_132.61_MB_(100.00%) import kotlin.math.max diff --git a/src/main/kotlin/g3601_3700/s3605_minimum_stability_factor_of_array/Solution.kt b/src/main/kotlin/g3601_3700/s3605_minimum_stability_factor_of_array/Solution.kt index 676de6f0..7d573f63 100644 --- a/src/main/kotlin/g3601_3700/s3605_minimum_stability_factor_of_array/Solution.kt +++ b/src/main/kotlin/g3601_3700/s3605_minimum_stability_factor_of_array/Solution.kt @@ -1,6 +1,7 @@ package g3601_3700.s3605_minimum_stability_factor_of_array -// #Hard #2025_07_07_Time_95_ms_(100.00%)_Space_77.89_MB_(100.00%) +// #Hard #Array #Math #Greedy #Binary_Search #Segment_Tree #Number_Theory +// #2025_07_07_Time_95_ms_(100.00%)_Space_77.89_MB_(100.00%) class Solution { fun minStable(nums: IntArray, maxC: Int): Int { diff --git a/src/main/kotlin/g3601_3700/s3606_coupon_code_validator/Solution.kt b/src/main/kotlin/g3601_3700/s3606_coupon_code_validator/Solution.kt index 0791174f..d39e3804 100644 --- a/src/main/kotlin/g3601_3700/s3606_coupon_code_validator/Solution.kt +++ b/src/main/kotlin/g3601_3700/s3606_coupon_code_validator/Solution.kt @@ -1,6 +1,7 @@ package g3601_3700.s3606_coupon_code_validator -// #Easy #2025_07_07_Time_32_ms_(100.00%)_Space_60.79_MB_(100.00%) +// #Easy #Array #String #Hash_Table #Sorting +// #2025_07_07_Time_32_ms_(100.00%)_Space_60.79_MB_(100.00%) class Solution { fun validateCoupons(code: Array, businessLine: Array, isActive: BooleanArray): List { diff --git a/src/main/kotlin/g3601_3700/s3607_power_grid_maintenance/Solution.kt b/src/main/kotlin/g3601_3700/s3607_power_grid_maintenance/Solution.kt index 46cc3ce1..b031c74f 100644 --- a/src/main/kotlin/g3601_3700/s3607_power_grid_maintenance/Solution.kt +++ b/src/main/kotlin/g3601_3700/s3607_power_grid_maintenance/Solution.kt @@ -1,6 +1,7 @@ package g3601_3700.s3607_power_grid_maintenance -// #Medium #2025_07_07_Time_91_ms_(100.00%)_Space_165.69_MB_(93.75%) +// #Medium #Array #Hash_Table #Depth_First_Search #Breadth_First_Search #Heap_Priority_Queue #Graph +// #Union_Find #Ordered_Set #2025_07_07_Time_91_ms_(100.00%)_Space_165.69_MB_(93.75%) import java.util.PriorityQueue diff --git a/src/main/kotlin/g3601_3700/s3608_minimum_time_for_k_connected_components/Solution.kt b/src/main/kotlin/g3601_3700/s3608_minimum_time_for_k_connected_components/Solution.kt index 1c36d592..cc753a66 100644 --- a/src/main/kotlin/g3601_3700/s3608_minimum_time_for_k_connected_components/Solution.kt +++ b/src/main/kotlin/g3601_3700/s3608_minimum_time_for_k_connected_components/Solution.kt @@ -1,6 +1,7 @@ package g3601_3700.s3608_minimum_time_for_k_connected_components -// #Medium #2025_07_07_Time_31_ms_(100.00%)_Space_114.78_MB_(100.00%) +// #Medium #Sorting #Binary_Search #Graph #Union_Find +// #2025_07_07_Time_31_ms_(100.00%)_Space_114.78_MB_(100.00%) class Solution { fun minTime(n: Int, edges: Array, k: Int): Int { diff --git a/src/main/kotlin/g3601_3700/s3609_minimum_moves_to_reach_target_in_grid/Solution.kt b/src/main/kotlin/g3601_3700/s3609_minimum_moves_to_reach_target_in_grid/Solution.kt index a344bb1d..8bf8f113 100644 --- a/src/main/kotlin/g3601_3700/s3609_minimum_moves_to_reach_target_in_grid/Solution.kt +++ b/src/main/kotlin/g3601_3700/s3609_minimum_moves_to_reach_target_in_grid/Solution.kt @@ -1,6 +1,6 @@ package g3601_3700.s3609_minimum_moves_to_reach_target_in_grid -// #Hard #2025_07_07_Time_1_ms_(100.00%)_Space_40.67_MB_(100.00%) +// #Hard #Math #2025_07_07_Time_1_ms_(100.00%)_Space_40.67_MB_(100.00%) class Solution { fun minMoves(sx: Int, sy: Int, tx: Int, ty: Int): Int { From 452ccd28cd5dee942ccf495f169c46f775f7e649 Mon Sep 17 00:00:00 2001 From: Valentyn Kolesnikov Date: Tue, 8 Jul 2025 10:10:03 +0300 Subject: [PATCH 4/4] Added test --- .../Solution.kt | 12 ++---------- .../SolutionTest.kt | 8 ++++++++ 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/main/kotlin/g3601_3700/s3608_minimum_time_for_k_connected_components/Solution.kt b/src/main/kotlin/g3601_3700/s3608_minimum_time_for_k_connected_components/Solution.kt index cc753a66..7fa82175 100644 --- a/src/main/kotlin/g3601_3700/s3608_minimum_time_for_k_connected_components/Solution.kt +++ b/src/main/kotlin/g3601_3700/s3608_minimum_time_for_k_connected_components/Solution.kt @@ -28,24 +28,16 @@ class Solution { private fun countComponents(n: Int, edges: Array, t: Int): Int { val parent = IntArray(n) - val size = IntArray(n) for (i in 0.. t) { - var u = find(parent, e[0]) - var v = find(parent, e[1]) + val u = find(parent, e[0]) + val v = find(parent, e[1]) if (u != v) { - if (size[u] < size[v]) { - val tmp = u - u = v - v = tmp - } parent[v] = u - size[u] += size[v] comps-- } } diff --git a/src/test/kotlin/g3601_3700/s3608_minimum_time_for_k_connected_components/SolutionTest.kt b/src/test/kotlin/g3601_3700/s3608_minimum_time_for_k_connected_components/SolutionTest.kt index 9c549b6b..953f1189 100644 --- a/src/test/kotlin/g3601_3700/s3608_minimum_time_for_k_connected_components/SolutionTest.kt +++ b/src/test/kotlin/g3601_3700/s3608_minimum_time_for_k_connected_components/SolutionTest.kt @@ -32,4 +32,12 @@ internal class SolutionTest { equalTo(0), ) } + + @Test + fun minTime4() { + assertThat( + Solution().minTime(3, arrayOf(intArrayOf(2, 1, 1469), intArrayOf(1, 0, 5701)), 2), + equalTo(1469), + ) + } }