一 題目描述算法
在一個排序矩陣中找從小到大的第 k 個整數。數組
排序矩陣的定義爲:每一行遞增,每一列也遞增。性能
二 題解spa
因爲排序矩陣中的每一行都是遞增的,而且每一列都是遞增的。從小到大第k個數,實際上就是第k小的數。思路以下:code
假設排序矩陣共有row行和col列,因爲每行是遞增的,咱們只要選擇出每行的最小數(一共row個)並從這row個數中選出最小的數來,重複這個過程k次,第k次選擇出的最小值就是整個矩陣中第k小的數。blog
代碼以下:排序
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,因此全部的行須要遍歷一一遍。io
2.在每次進行row輪循環的時候,必定不要忘記判斷,相應的值的列數的索引是否已經達到最大值。class
3.注意minRows數組更新的時候是在row輪循環結束的後才進行更新。
============================================================================================================
此外,本題是從列的角度來考慮的,即每次找出一列數中的最小值來;,固然也可從行的角度來考慮,每次找出一行數中的最小值來,重複k次,第k次的最小值就是最終結果。兩種方法思想相似,利用第二種方法的話時間複雜度就變成了O(k*col)。
當列數大於行數的時候,用第一種方法比較好;而當行數大於列數的時候用第二種方法比較好,固然前提是行數和列數的差值比較大,不然兩種方法性能差很少;固然,也能夠結合這兩種狀況,對於行列數不一樣的狀況時,採用不一樣方法。