上街区网站建设,不想花钱做网站推广,wordpress 文章 形式,专业网站建设公司兴田德润优惠吗这是二分法的第19篇算法#xff0c;力扣链接。 给你一个 n x n 矩阵 matrix #xff0c;其中每行和每列元素均按升序排序#xff0c;找到矩阵中第 k 小的元素。 请注意#xff0c;它是 排序后 的第 k 小元素#xff0c;而不是第 k 个 不同 的元素。 你必须找到一个内存复杂…这是二分法的第19篇算法力扣链接。 给你一个 n x n 矩阵 matrix 其中每行和每列元素均按升序排序找到矩阵中第 k 小的元素。 请注意它是 排序后 的第 k 小元素而不是第 k 个 不同 的元素。 你必须找到一个内存复杂度优于 O(n2) 的解决方案。 示例 1 输入matrix [[1,5,9],[10,11,13],[12,13,15]], k 8
输出13
解释矩阵中的元素为 [1,5,9,10,11,12,13,13,15]第 8 小元素是 13 这道题很抽象他告诉我们行和列都是有序的。但是不代表下一列一定大于上一行。
老规矩直接上暴力法先把所有数字存起来然后排序。
func kthSmallest(matrix [][]int, k int) int {nums : make([]int, len(matrix)*len(matrix[0]))index : 0for _, row : range matrix {for _, num : range row {nums[index] numindex}}sort.Ints(nums)return nums[k-1]
}
那这道题二分法怎么搞呢
首先明确无论这个分布怎么诡异在matrix[0][0]的数一定matrix[len(matrix)-1][len(matrix[0])-1]的数小。我门可以利用这两个值当作边界往中间找mid移动左右边界的逻辑可以根据小于等于mid的数的多少。当左右指针相等的时候返回指针就可以了。
这时候还会有一个疑问当左右指针相等的时候那个边界的值真的存在吗这个值不是根据mid左右移动算出来的吗。
其实很简单求出矩阵元素排序后把矩阵分成两份且使得前一份包含k个元素的数值范围左边界值(满足条件的数值可能是个范围有些值不存在矩阵中但这个左边界值一定在矩阵中)。可以尝试去推导一下会发现这个结论是存在的。
上代码
func kthSmallest(matrix [][]int, k int) int {l, r : matrix[0][0], matrix[len(matrix)-1][len(matrix[0])-1]for l r {mid : l (r-l)/2if count(mid, matrix) k {l mid 1} else {r mid - 1}}return l
}func count(mid int, matrix [][]int) int {result, x, y : 0, len(matrix)-1, 0for x 0 y len(matrix[0]) {if matrix[x][y] mid {result x 1y} else {x--}}return result
}
这个count是有点学问的这个是一列一列的加数字梯形的方式加。