版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u011718609/article/details/77822166
在一个排序矩阵中找从小到大的第 k 个整数。
排序矩阵的定义为:每一行递增,每一列也递增。
样例如下:
给出k = 4和如下排序数组
[
[1, 5, 7],
[3, 6, 8],
[4, 9, 10]
]
返回结果为5
有两个思路,1)直接按从小到大顺序找,找K次,每次找最小的元素,时间复杂度为O(k*N); 2)采用最小堆,时间复杂度为O(K*logN);最小堆用优先队列实现
#include<iostream>
#include<vector>
#include<string>
#include<queue>
#include<utility>
using namespace std;
vector<vector<int>> *ma;
class cmp
{
public:
bool operator()(const pair<int, int> &a, const pair<int, int> &b)
{
return (*ma)[a.first][a.second] > (*ma)[b.first][b.second];
}
};
/*采用最小堆的方式实现,O(k*log(N))*/
int findKthMin1(vector<vector<int>> &matrix, unsigned int k)
{
int n = matrix.size();
int m = matrix[0].size();
vector<vector<int>> visit(n, vector<int>(m));
//初始化最小堆
priority_queue<pair<int, int>, vector<pair<int, int>>, cmp> q;
q.push(make_pair(0, 0));
visit[0][0] = true;
while (k--)
{
pair<int, int> p = q.top();
if (k == 0)
break;
q.pop();
int x = p.first;
int y = p.second;
if (x + 1 < n && visit[x + 1][y] == false)
{
visit[x + 1][y] = true;
q.push(make_pair(x + 1, y));
}
if (y + 1 < m && visit[x][y + 1] == false)
{
visit[x][y + 1] = true;
q.push(make_pair(x, y + 1));
}
}
pair<int, int> p = q.top();
return matrix[p.first][p.second];
}
/*采用线型搜索,O(K*N)*/
int findKthMin2(vector<vector<int>> &matrix, unsigned int k)
{
int n = matrix.size();
int m = matrix[0].size();
int result = 0;
vector<int> rows(n);
for (int i = 0; i < n; i++)
{
rows[i] = 0; //记录第i行所在的列数
}
//找k次,每次找最小的,在对应行向右移1列
for(int cnt = 0; cnt < k; cnt++)
{
int temp = INFINITY;
int flag = 0;
for (int i = 0; i < n; i++)
{
if (rows[i] < m)
{
if (matrix[i][rows[i]] < temp)
{
temp = matrix[i][rows[i]];
flag = i;
}
}
}
rows[flag]++;
result = temp;
}
return result;
}
int main()
{
int k, n, m;
// 输入k,n,m
cin >> k >> n >> m;
vector<vector<int>> matrix(n, vector<int>(m));
// 输入排序矩阵
for (int i = 0; i < n; i++)
{
for (int j = 0; j < m; j++)
{
cin >> matrix[i][j];
}
}
ma = &matrix; //关联全局变量ma
//采用最小堆
int Kth1 = findKthMin1(matrix, k);
//线性搜索
int Kth2 = findKthMin2(matrix, k);
cout << Kth1 << Kth2;
system("pause");
return 0;
}