编程题:行和列已排序的矩阵,求其从小到大的第k个元素。
作者:互联网
问题,已知矩阵,例如:
每一行和每一列都是递增的,求从小到大排的第个元素是多少?
方法1:基本思路是从最小的元素开始找,依次找,直到找到第个元素,由于每一行都是递增的,可以在每一行都设定一个起始读位置index,表示该行已读取几个元素,下一次要读取该行的哪个元素,每次读取每一行的一个元素,那么这些元素的必然有一个是最小值,取出最小的元素,相应的行的index加1。以我们给出的矩阵为例,最开始所有行均从0开始,我们扫描所有行的首元素,第一个读取的是且第一行的index变为1,其他行不变,继续扫描,第二个读的是,第二行的index变为1,这样一次读下去,直到取第个元素。设行数为,由于每次都会做次查找故复杂度为,代码实现如下:
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=new int[row]();//用于存储每行的读取索引位置,并初始化为0。
if (k > row * col || k<0)//防止错误。
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;
}
delete [] minRows;
return rs;
}
方法2:进一步利用矩阵的行列均递增的特性,首先可以确定肯定是最小的,那么第二步呢,我们要找剩下的里面最小的,显然不能直接找到,但可以确定最小必然是或,这就是我们的思路,虽然找不到剩下最小的,但可以找到最小的集合,这样对这个集合排序,取出最小的元素就可以了。这样,我们得到了我们整体的思路,读取第一个元素之后开始,我们维持一个可能含有最小元素的集合,这个集合是排序的,取出一个就是最小的,那么每次取出第一个最小的之后,可能的最小元素只可能会是最小元素右边和下边的两个元素(可能不存在)与之前最小元素集合的并集,这样依次递推直到取出第个即可,排序集合可以用priority_queue实现,每次会弹出最顶上的最小元素,其复杂度为,我们给出代码实现:
int kthSmallest(vector<vector<int>> matrix, int k) {
if (matrix.empty() || k <= 0)
return 0;
priority_queue<pair<int, int>, vector<pair<int, int>>, greater<pair<int, int>>> que;
int row = matrix.size();
int col = matrix[0].size();
vector<vector<int>> visited(row, vector<int>(col, 0));
que.push(make_pair(matrix[0][0], 0 * col + 0));
visited[0][0] = 1;
while (k--)
{
auto pairVal = que.top();
que.pop();
if (k == 0)
return pairVal.first;
int i = pairVal.second / col;
int j = pairVal.second%col;
if (i + 1 < row&&visited[i + 1][j] == 0)
{
que.push(make_pair(matrix[i + 1][j], (i + 1)*col + j));
visited[i + 1][j] = 1;
}
if (j + 1 < col&&visited[i][j + 1] == 0)
{
que.push(make_pair(matrix[i][j + 1], i*col + (j + 1)));
visited[i][j + 1] = 1;
}
}
}
标签:编程,matrix,int,元素,行和列,最小,求其,col,row 来源: https://blog.csdn.net/fangfanglovezhou/article/details/112758922