給定乙個 n x n 矩陣,其中每行和每列元素均按公升序排序,找到矩陣中第 k 小的元素。
請注意,它是排序後的第 k 小元素,而不是第 k 個不同的元素。
matrix = [
[ 1, 5, 9],
[10, 11, 13],
[12, 13, 15]
],k = 8,
返回 13。
該題目在力扣中屬於中等難度,因此確實是有些難到我了?,不過沒事,最終在答案和思考的雙重攻勢下,還是搞出來了。這裡我總共有兩種方法
1 放入一堆陣列後排序
開始的時候,我是直接暴力遍歷放入陣列,利用選排排序之後,直接return,但是最大資料時超時了,這讓我意識到果然中等題目不是這麼簡單,但是我換了一種qsort方法之後它卻並未過時,所以我想還是我用的演算法時間太高了。
這裡我並不推薦使用stdlib.**件中的qsort函式,因為該函式雖然可以對多種資料結構進行排序,但是就演算法角度來說屬於取巧
一般我們需要手寫乙個函式對其進行配套使用
int
cmp(
const
void
*a,const
void
*b)//降序,qsort函式預設公升序,而實現公升序規則只需調換成a-b的形式即可
void
qsort
(rec, num,
sizeof
(int
), cmp)
;
這樣的qsort函式可以直接對陣列進行排序,答案**:
int
cmp(
const
void
*a,const
void
*b)//a-b為公升序,b-a為降序 這裡我們使用公升序
intkthsmallest
(int
**matrix,
int matrixsize,
int*matrixcolsize,
int k)
}qsort
(b, num,
sizeof
(int
), cmp)
;//cmp為函式指標
return b[k -1]
;}
2 二分法求值
二分法我覺得就演算法角度來說是最適合的做這道題目的。
首先我們的思想一定要貼切二分法,我們從題目不難得知,陣列從左上角為最小記為left,右邊一定大於左邊,下邊一定大於右邊,那便不難得到,最大的數一定是在右下角記為right,我們從陣列中任取乙個數字mid也不難得到left<=mid<=right,這樣的話,我們開始隨機取乙個mid並從左下角開始計數,如果數字小於mid則往右走一步,否則往上走一步,走出去後我們便能得到小於mid的數字的個數num,如果那個k<=num則說明,我們需要的數字不大於mid,於是我們讓右界right復位mid,如果k>num則說明我們需要的數字大於mid,於是我們讓左界left=mid+1繼續算,直到我們的left等於right返回left或者right都可以。
**:
bool check
(int
**matrix,
int mid,
int k,
int n)
else
i--;}
return num >= k;
//這裡直接返回true或者false
}int
kthsmallest
(int
**matrix,
int matrixsize,
int*matrixcolsize,
int k)
return left;
}
結果:
力扣 378 有序矩陣中第K小的元素
思路 顯然易得矩陣最小值為m 0 0 m 0 0 m 0 0 最大值為m n 1 n 1 m n 1 n 1 m n 1 n 1 那麼我們可以二分第k kk小元素的值mid midmi d,再遍歷矩陣的每一行 或列 判斷 m id mid m id的數的總和,假設為num numnu m,如果num...
力扣第378題 有序矩陣中第K小的元素
給定乙個 n x n 矩陣,其中每行和每列元素均按公升序排序,找到矩陣中第 k 小的元素。請注意,它是排序後的第 k 小元素,而不是第 k 個不同的元素。示例 matrix 1,5,9 10,11,13 12,13,15 k 8,返回 13。解法1 使用flat 加上sort 之後根據index進行...
378 有序矩陣中第K小的元素
378.有序矩陣中第k小的元素 給定乙個n x n矩陣,其中每行和每列元素均按公升序排序,找到矩陣中第k小的元素。請注意,它是排序後的第k小元素,而不是第k個不同的元素。示例 matrix 1,5,9 10,11,13 12,13,15 k 8,返回 13。你可以假設 k 的值永遠是有效的,1 k ...