一 题目描述算法
在一个排序矩阵中找从小到大的第 k 个整数。数组
排序矩阵的定义为:每一行递增,每一列也递增。性能
二 题解spa
因为排序矩阵中的每一行都是递增的,而且每一列都是递增的。从小到大第k个数,实际上就是第k小的数。思路以下:blog
假设排序矩阵共有row行和col列,因为每行是递增的,咱们只要选择出每行的最小数(一共row个)并从这row个数中选出最小的数来,重复这个过程k次,第k次选择出的最小值就是整个矩阵中第k小的数。排序
代码以下:索引
class Solution { public: /** * @param matrix: a matrix of integers * @param k: An integer * @return: the kth smallest number in the matrix */ int kthSmallest(vector<vector<int>> &matrix, int k) { size_t row = matrix.size(); size_t col = matrix[0].size(); if(row == 0 || col == 0) return -1; int minRows[row];//用于存储每行的最小值对应的列数 memset(minRows,0,sizeof(minRows));//对minRows初始化,且初始值都为0 if(k > row * col)//错误处理 return -1; int rs; int tmp; for(int cnt = 1; cnt <= k; cnt++) { int min_val = INT_MAX;//每次比较都须要初始化,注意该变量定义的位置 for(int row_index = 0; row_index < row; row_index++) { if(minRows[row_index] < col)//注意这个判断条件必定要加上,防止越界 { if(matrix[row_index][minRows[row_index]] < min_val) { min_val = matrix[row_index][minRows[row_index]]; tmp = row_index; } } } minRows[tmp]++;//更新相应行中最小值的位置,要注意此处的位置,是在row轮循环以后才能找出最小值 if(cnt == k) rs = min_val; } return rs; } };
该算法思路表简单,算法的时间复杂度为O(k*row),此外,有几个须要注意的地方:io
1.咱们每次选择出的最小值指的是这row个数中的最小值,因此mi_val这个变量须要在每次循环开始的时候才定义,这里我定义的是INT_MAX,因此全部的行须要遍历一一遍。class
2.在每次进行row轮循环的时候,必定不要忘记判断,相应的值的列数的索引是否已经达到最大值。变量
3.注意minRows数组更新的时候是在row轮循环结束的后才进行更新。
============================================================================================================
此外,本题是从列的角度来考虑的,即每次找出一列数中的最小值来;,固然也可从行的角度来考虑,每次找出一行数中的最小值来,重复k次,第k次的最小值就是最终结果。两种方法思想相似,利用第二种方法的话时间复杂度就变成了O(k*col)。
当列数大于行数的时候,用第一种方法比较好;而当行数大于列数的时候用第二种方法比较好,固然前提是行数和列数的差值比较大,不然两种方法性能差很少;固然,也能够结合这两种状况,对于行列数不一样的状况时,采用不一样方法。