找到排序矩陣中從小到大第K個數字


一 題目描述

在一個排序矩陣中找從小到大的第 k 個整數。

排序矩陣的定義為:每一行遞增,每一列也遞增。

二 題解

由於排序矩陣中的每一行都是遞增的,並且每一列都是遞增的。從小到大第k個數,實際上就是第k小的數。思路如下:

假設排序矩陣共有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),此外,有幾個需要注意的地方:

1.我們每次選擇出的最小值指的是這row個數中的最小值,所以mi_val這個變量需要在每次循環開始的時候才定義,這里我定義的是INT_MAX,所以所有的行需要遍歷一一遍。

2.在每次進行row輪循環的時候,一定不要忘記判斷,相應的值的列數的索引是否已經達到最大值。

3.注意minRows數組更新的時候是在row輪循環結束的后才進行更新。

============================================================================================================

此外,本題是從列的角度來考慮的,即每次找出一列數中的最小值來;,當然也可從行的角度來考慮,每次找出一行數中的最小值來,重復k次,第k次的最小值就是最終結果。兩種方法思想類似,利用第二種方法的話時間復雜度就變成了O(k*col)。

當列數大於行數的時候,用第一種方法比較好;而當行數大於列數的時候用第二種方法比較好,當然前提是行數和列數的差值比較大,否則兩種方法性能差不多;當然,也可以結合這兩種情況,對於行列數不同的情況時,采用不同方法。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2026 CODEPRJ.COM