文章目录
- 前言
- 一、有序矩阵中第K小的元素是什么?
- 二、具体实现
前言
运用Scala中的语法实现有序矩阵中第K小的元素
一、有序矩阵中第K小的元素是什么?
给定一个 n x n 矩阵,其中每行和每列元素均按升序排序,找到矩阵中第 k 小的元素。 请注意,它是排序后的第 k 小元素,而不是第 k 个不同的元素。 示例: matrix = [ [ 1, 5, 9], [10, 11, 13], [12, 13, 15] ], k = 8, 返回 13。
二、具体实现
代码如下(示例):
这就是二分法的思路。假定查找的范围为[left, right],首先计算int mid = left + (right - left) / 2,
然后在矩阵中计数有多少个元素小于等于mid,这个数量为count。
如果count < k,那么第k小的数至少为mid + 1,所以left = mid + 1。
反之,right = mid。
循环结束的条件为left >= right,此时left即为答案。
def kthSmallest(matrix: Array[Array[Int]], k: Int): Int = {
val len=matrix.length-1
//二分法的思路。假定查找的范围为[left, right]
var left=matrix(0)(0)//left的初始值为数组中的最小值
var right=matrix(len)(len)//right的初始值为数组中的最大值
while (left < right){
val mid=left+(right-left)/2
val count=countNotMoreThanMid(matrix, mid, len);//统计多少个数小于mid
if (count < k)//如果count < k,那么第k小的数至少为mid + 1,所以left = mid + 1。
left=mid+1
else//反之,第k小的数最多为mid + 1,right = mid。
right=mid
}
left
}
def countNotMoreThanMid(matrix: Array[Array[Int]], mid: Int, len: Int)={
var count = 0
var i=0
var j=len
//从左下角开始找
while (i<=len && j>=0)
if(matrix(i)(j) <= mid){//如何mid值大于当前值,肯定大于当前值所在列的前j行值
count += j + 1;//count=j+1
i+=1//往右移动一列
}else{
j-=1如何mid值小于当前值,往上移动一行
}
count
}
例如 mid=8:
我们可以看到,矩阵中大于 midmid 的数就和不大于 midmid 的数分别形成了两个板块,沿着一条锯齿线将这个矩形分开。其中左上角板块的大小即为矩阵中不大于 midmid 的数的数量。