求陣列中第K大的數

2021-08-08 01:51:50 字數 1833 閱讀 3091

本題的的陣列是可以包含重複元素的,且要求時間複雜度控制在o(n)

解題思路:陣列中第k大的數等價於排序陣列中第n-k個數,直觀的想法是將陣列排序後取第n-k個數即可,但是最快的排序演算法時間複雜度也是o(nlogn), 可以參考快速排序一次劃分的思想,將時間複雜度降低為o(n);一次劃分可以講陣列分為三部分,比支點元素小或者與支點元素相等的部分,支點元素,比支點元素的部分。一次partition之後,可以得到這個支點元素的下標,並且這個下標,也就是說這個數字在陣列中的位置已經確定,它就是第n-index大的數,因此我們可以在一次劃分後,比較由這次劃分所確定的元素的下標index和n-k比較,如果相等,則arr[index]就是第n-k個數;若index> n - k,則證明第k大的數在 index的左邊,繼續在左邊進行一次劃分,;若index < n -k,則第k大的數在index的右邊,繼續在右邊進行一次劃分,直到使得index == n- k 為止。這裡運用了分治的思想。

public class main 

int length = arr.length;

int start = 0;

int end = length - 1;

// 對陣列進行一次劃分

int index = partition(arr, start, end);

//直到index為第n-k個數為止

while (index != length - k) else

} return arr[index];

} /**

* @param arr

* 帶劃分的陣列

* @param start

* 陣列的起始位置

* @param end

* 陣列的結束位置 return 返回陣列中某個元素的索引,索引左邊的元素都比該元素小或者相等,索引右邊的元素都比索引元素大

*/public static int partition(int arr, int start, int end)

// 將陣列的起始元素作為支點元素

int pivot = arr[start];

// left從陣列最左邊開始,往右移,直到找到乙個比支點元素大的,待放入到陣列的右半部分

int left = start;

// right從陣列的最右邊開始,往左移,直到找到乙個比支點元素小的或者相等的,待放入到陣列的左半部分

// 那麼當left和right交叉時,right肯定是指向比支點元素小或者和支點元素想等的元素,此時right可以作為分界線

// right左邊都是比支點元素小的或者相等的,right右邊肯定是比支點元素大的

int right = end;

while (left < right)

// right一直左移,直到找到乙個比支點元素小或者和支點元素相等的元素,待交換到陣列的左邊

while (arr[right] > pivot)

if (left < right)

} // 當left和right錯開後,此時已經將陣列分成兩個部分,right指向之前的包括right指向的元素都和支點元素相等或比支點元素小

// left指向之後的元素包括left指向元素都比支點元素大

// 將支點元素和right指向元素進行交換,right作為陣列的分割點

arr[start] = arr[right];

arr[right] = pivot;

return right;

} private static void swqp(int arr, int left, int right)

}

求陣列中第k大的數

文章裝載自 使用快排,第一趟快排過後,右邊的元素都比樞軸大,左邊的都比樞軸小。當我們要求第k大的數,只需要左邊的元素個數是len k,len是陣列總長度。第一次快排下來,設樞軸位置是mid,如果mid k,說明第k大元素應該在左邊序列中,遞迴左邊序列。當 mid k 時,說明k元素在右邊序列,遞迴右...

求陣列第K大的數

問題 有乙個大小為n的陣列a 0,1,2,n 1 求其中第k大的數。我們先分析原問題 有乙個大小為 n的陣列a 0,1,2,n 1 求其中第k大的數。我們先取特例,令k 1,那麼就是取最大的數,只要掃瞄一遍陣列就可以確定該值,如果k 2,則掃瞄兩邊陣列就可以確定第二大的數,依此類推下去,時間複雜度是...

C 堆 heap 求陣列中第K大的數

已知乙個未排序的陣列,求這個陣列中第k大的數字。思路 維護乙個k大小的最小堆,堆中元素個數小於k時,新元素直接進入堆 否則 當堆頂小於新元素時,彈出堆頂,將新元素加入堆。解釋 由於堆是最小堆,堆頂是堆中最小元素,新元素都會保證比堆頂小,否則新元素替換堆頂,故堆中k個元素是已掃瞄的元素裡最大的k個 堆...