一、題目描述
給定一個 n x n 矩陣,其中每行和每列元素均按升序排序,找到矩陣中第 k 小的元素。
請注意,它是排序後的第 k 小元素,而不是第 k 個不同的元素。
二、示例
三、解題思路
- 第一種思路是我們可以直接暴力求解,將二維數組展平,再去尋找第K個元素
- 第二種思路我們可以使用二分法來達到目的:
a、確定值的範圍是在數組的matrix[0][0]到matrix[n-1][n-1]之間,
b、再去找到中間值,並且算出該數組中比當前值小的個數count
c、將count與k比較,如果count比k小的話說明在中間值的右半部分,(要輸出這個第k個值),將左邊界變成中間值+1,反之亦然。
d、如果計算第b步驟中的count呢,我們這樣想,因爲目前的數組是從左到右,從上到下的升序的,所以我們和每一行的最後一個進行比較,若當前的中間值大於行的最後一列的那個數字時表明該行的數都是小於中間值的數字,count+=該行的個數,row++,比較下一行,如果小於的話,則clumn–來進行判斷,最後返回count就是要求的值。
四、代碼
//第一種(暴力求解)
/**
* @param {number[][]} matrix
* @param {number} k
* @return {number}
*/
var kthSmallest = function(matrix, k) {
var newArr = []
matrix.forEach(item=>{
newArr = newArr.concat(item)
})
newArr.sort((a,b)=>{return a-b})
return newArr[k - 1]
};
//第二種(二分求解)
/**
* @param {number[][]} matrix
* @param {number} k
* @return {number}
*/
const getCount = (matrix,midd)=>{
let n = matrix.length
let row = 0;
let column = n-1
let count =0
while(row<n && column>=0){
if(midd>=matrix[row][column]){
count+=column+1
row++;
}
else{
column--;
}
}
return count
}
var kthSmallest = function(matrix, k) {
const n = matrix.length
let low= matrix[0][0]
let high = matrix[n-1][n-1]
while(low<=high){
let mid = low + ((high - low) >>> 1);
let count = getCount(matrix,mid)
if(count<k){
low = mid+1
}else{
high = mid-1
}
}
return low
};