C語言 力扣 378 有序矩陣中第K小的元素

2021-10-08 06:26:41 字數 1979 閱讀 5325

給定乙個 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 ...