使用kotlin解决这个问题:1439. 有序矩阵中的第 k 个最小数组和 给你一个 m * n 的矩阵 mat,以及一个整数 k ,矩阵中的每一行都以非递减的顺序排列。 你可以从每一行中选出 1 个元素形成一个数组。返回所有可能数组中的第 k 个 最小 数组和。 示例 1: 输入:mat = [[1,3,11],[2,4,6]], k = 5 输出:7 解释:从每一行中选出一个元素,前 k 个和最小的数组分别是: [1,2], [1,4], [3,2], [3,4], [1,6]。其中第 5 个的和是 7 。 示例 2: 输入:mat = [[1,3,11],[2,4,6]], k = 9 输出:17 示例 3: 输入:mat = [[1,10,10],[1,4,5],[2,3,6]], k = 7 输出:9 解释:从每一行中选出一个元素,前 k 个和最小的数组分别是: [1,1,2], [1,1,3], [1,4,2], [1,4,3], [1,1,6], [1,5,2], [1,5,3]。其中第 7 个的和是 9 。 示例 4: 输入:mat = [[1,1,10],[2,2,9]], k = 7 输出:12 提示: m == mat.length n == mat.length[i] 1 <= m, n <= 40 1 <= k <= min(200, n ^ m) 1 <= mat[i][j] <= 5000 mat[i] 是一个非递减数组
时间: 2023-07-02 16:15:48 浏览: 86
两个有序数序列中找第k小(必做)
以下是使用 Kotlin 解决这个问题的代码:
```kotlin
fun kthSmallest(mat: Array<IntArray>, k: Int): Int {
var left = 0
var right = 0
for (i in 0 until mat.size) {
left += mat[i][0]
right += mat[i][mat[i].size - 1]
}
var result = left
while (left <= right) {
val mid = (left + right) / 2
val count = countArrays(mat, 0, mid, 0, k)
if (count >= k) {
result = mid
right = mid - 1
} else {
left = mid + 1
}
}
return result
}
fun countArrays(mat: Array<IntArray>, row: Int, target: Int, sum: Int, k: Int): Int {
if (sum > target || sum + (mat.size - row) * mat[0].size < target) {
return 0
}
if (row == mat.size) {
return 1
}
var count = 0
for (i in 0 until mat[0].size) {
count += countArrays(mat, row + 1, target, sum + mat[row][i], k - count)
if (count >= k) {
break
}
}
return count
}
```
这个算法的时间复杂度为 O(k log s),其中 s 为矩阵中所有元素的和。具体来说,我们首先计算出所有可能数组中的最小和 left 和最大和 right,然后使用二分查找在这个范围内查找第 k 小的数组和。在每次二分查找时,我们使用回溯法统计小于等于 mid 的数组和的数量,如果数量大于等于 k,则说明 mid 可能是符合条件的数,我们将右边界缩小到 mid,否则我们将左边界扩大到 mid + 1。在回溯法中,我们使用递归遍历每一行中的所有元素,计算所有可能的数组和,并返回小于等于 target 的数组和的数量。
以下是这个算法的测试代码:
```kotlin
fun main() {
val mat1 = arrayOf(intArrayOf(1, 3, 11), intArrayOf(2, 4, 6))
println(kthSmallest(mat1, 5)) // 输出 7
println(kthSmallest(mat1, 9)) // 输出 17
val mat2 = arrayOf(intArrayOf(1, 10, 10), intArrayOf(1, 4, 5), intArrayOf(2, 3, 6))
println(kthSmallest(mat2, 7)) // 输出 9
val mat3 = arrayOf(intArrayOf(1, 1, 10), intArrayOf(2, 2, 9))
println(kthSmallest(mat3, 7)) // 输出 12
}
```
阅读全文