排序矩阵(杨氏矩阵)找从小到大的第K个数(C++)

版权声明:本文为博主原创文章,未经博主允许不得转载。 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;
}

猜你喜欢

转载自blog.csdn.net/u011718609/article/details/77822166
今日推荐