在無序陣列中找到第k大的數
在N個元素中查詢第K大元素,一般比較簡單的方法就是先快速排序,然後直接返回array[N - K]或者利用掃描法,每一次掃描都找到當前陣列中最大的元素,這個其實就是部分氣泡排序。前一種演算法的時間複雜度是O(NlogN),後一種演算法的時間複雜度是K*N。當然,這裡我們不打算具體討論以上兩種方案,接下來看看其他方法。
第一種方法:利用堆排序的思想來查詢陣列中第K大元素。首先提取子陣列array[0...K-1]並構造小頂堆,然後把剩下子陣列array[K...N-1]中的所有元素與堆頂元素array[0]進行比較,若大於堆頂元素,則進行交換並重新構造子陣列array[0...K-1]使其滿足小頂堆的要求。這樣的話,最後子陣列array[0...K-1]就是N個元素中的前K個最大元素,堆頂array[0]就是N個元素中的第K大元素。具體實現程式碼如下:
- #include <cstdlib>
- #include <iostream>
- usingnamespace std;
- /*****************************************************************************
- 函 數 名 : small_heap_adjust
- 功能描述 : 根據陣列構建小頂堆
- 輸入引數 : array 待調整的堆陣列
- index 待調整的陣列元素的位置
- length 陣列的長度
-
輸出引數 : 無
- 返 回 值 : 無
- 修改歷史 :
- 1.日 期 : 2012/09/10
- 作 者 : liguangting
- 修改內容 :
- *****************************************************************************/
- void small_heap_adjust(int *array, int index, int length)
- {
- int child;
- int temp = array[index];
-
if (2 * index + 1 >= length)
- {
- return;
- }
- //子結點位置 = 2 * 父結點位置 + 1
- child = 2 * index + 1;
- //得到子結點中較小的結點
- if (child < length - 1 && array[child + 1] < array[child])
- {
- ++child;
- }
- //如果較小的子結點小於父結點那麼把較小的子結點往上移動,替換它的父結點
- if (temp > array[child])
- {
- array[index] = array[child];
- }
- else
- {
- return;
- }
- //最後把需要調整的元素值放到合適的位置
- array[child] = temp;
- small_heap_adjust(array, child, length);
- }
- /*****************************************************************************
- 函 數 名 : find_kmax_value
- 功能描述 : 查詢陣列中第K大元素
- 輸入引數 : array 待查詢的陣列
- length 陣列的長度
- K 第K大
- 輸出引數 : 無
- 返 回 值 : 返回第K大元素
- 修改歷史 :
- 1.日 期 : 2012/09/10
- 作 者 : liguangting
- 修改內容 :
- *****************************************************************************/
- int find_kmax_value(int *array, int length, int k)
- {
- int i = 0;
- //把子陣列array[0...k-1]構造成小頂堆
- for (i = k / 2 - 1; i >= 0; i--)
- {
- small_heap_adjust(array, i, k);
- }
- //子陣列array[k...length-1]的所有元素與堆頂元素進行比較,若大於堆頂元素
- //則交換,並重新調整堆
- for (i = k; i < length; i++)
- {
- if (array[i] > array[0])
- {
- swap(array[0], array[i]);
- small_heap_adjust(array, 0, k);
- }
- }
- return array[0];
- }
- int main(int argc, char *argv[])
- {
- constint LENGTH = 100;
- constint K = 30;
- int array[LENGTH] = {0};
- int kmax = 0;
- srand(time(NULL));
- cout << "原始陣列:" << endl;
- for (int i = 0; i < LENGTH; i++)
- {
- array[i] = rand() % 100;
- cout << array[i] << " ";
- if (0 == (i + 1) % 10)
- {
- cout << endl;
- }
- }
- kmax = find_kmax_value(array, LENGTH, K);
- cout << "第K大元素:" << kmax << endl;
- sort(array, array + LENGTH);
- cout << "排序後陣列:" << endl;
- for (int i = 0; i < LENGTH; i++)
- {
- cout << array[i] << " ";
- if (0 == (i + 1) % 10)
- {
- cout << endl;
- }
- }
- if (kmax == array[LENGTH - K])
- {
- cout << "查詢第K大元素成功!" << endl;
- }
- system("PAUSE");
- return EXIT_SUCCESS;
- }
第二種方法:同樣是利用堆排序的思想,但採用的是大頂堆,並且結合部分排序的思想。大致思路:首先把陣列array[0...N-1]構造成大頂堆,然後依次提取當前堆中最大的元素,直到找到第K大元素。具體實現程式碼如下:
- /*****************************************************************************
- 函 數 名 : big_heap_adjust
- 功能描述 : 根據陣列構建大頂堆
- 輸入引數 : array 待調整的堆陣列
- index 待調整的陣列元素的位置
- length 陣列的長度
- 輸出引數 : 無
- 返 回 值 : 無
- 修改歷史 :
- 1.日 期 : 2012/09/10
- 作 者 : liguangting
- 修改內容 :
- *****************************************************************************/
- void big_heap_adjust(int *array, int index, int length)
- {
- int child;
- int temp = array[index];
- if (2 * index + 1 >= length)
- {
- return;
- }
- //子結點位置 = 2 * 父結點位置 + 1
- child = 2 * index + 1;
- //得到子結點中較大的結點
- if (child < length - 1 && array[child + 1] > array[child])
- {
- ++child;
- }
- //如果較大的子結點大於父結點那麼把較大的子結點往上移動,替換它的父結點
- if (temp < array[child])
- {
- array[index] = array[child];
- }
- else
- {
- return;
- }
- //最後把需要調整的元素值放到合適的位置
- array[child] = temp;
- big_heap_adjust(array, child, length);
- }
- /*****************************************************************************
- 函 數 名 : find_kmax_value
- 功能描述 : 查詢陣列中第K大元素
- 輸入引數 : array 待查詢的陣列
- length 陣列的長度
- K 第K大
- 輸出引數 : 無
- 返 回 值 : 返回第K大元素
- 修改歷史 :
- 1.日 期 : 2012/09/10
- 作 者 : liguangting
-
相關推薦
尋找無序陣列中的第K大數和前K大數
兩個問題互相可以轉化。如果可以找到第K大數,那麼只再需要O(N)就可以找齊剩餘的前K大數。如果可以找到前K大數,那麼只再需要O(K)就可以找到第K大數。 先排序,在找第K個。O(NlgN) 快速排序的思想,可以做到平均效率O(N) 隨機選一個元素,把所有小於等於這個元素
經典演算法題:無序整數陣列中找第k大的數
經典問題:寫一段程式,找出陣列中第k大的數,輸出數所在的位置。 【解法一】先排序,然後輸出第k個位置上的數 我們先假設元素的數量不大,例如在幾千個左右,在這種情況下,那我們就排序一下吧。在這裡,快速排序或堆排序都是不錯的選擇,他們的平均時間複雜度 都是 O(N * logN
python:無序陣列中尋找第K大的元素
題目: 所謂“第(前)k大數問題”指的是在長度為n(n>=k)的亂序陣列中S找出從大到小順序的第(前)k個數的問題。 解法1:堆排序 採用元素下沉法,維護一個k大小的最小堆,對於陣列中的每一
兩個排序陣列中找第k大的數
一、問題給定兩個已經排序好的陣列,找到兩者所有元素中第k大的元素二、解法一:merge--將兩個有序陣列變成一個有序陣列時間複雜度O(m+n),空間複雜度O(m+n)/************************************************* 給定兩個
基於快排實現,在N個亂序的陣列中找第K大的數(Java實現)
類似於快速排序,執行一次快速排序之後,每次只選擇一部分繼續執行快速排序,直到找到第K大個元素為止,這個元素在陣列位置後面的元素即為所求。 時間複雜度:O(n) 利用快排的思想,從陣列arr中隨機找出一個元素X,把陣列分成兩部分arr_a和arr_b。 arr_a中的元素比x大,arr_b中的元素比x小。 這
在無序陣列中找到第k大的數
在N個元素中查詢第K大元素,一般比較簡單的方法就是先快速排序,然後直接返回array[N - K]或者利用掃描法,每一次掃描都找到當前陣列中最大的元素,這個其實就是部分氣泡排序。前一種演算法的時間複雜度是O(NlogN),後一種演算法的時間複雜度是K*N。當然,這裡我們不
由無序陣列中找到第K 大的元素
當然如果我們想要實現這個問題會有很多思路,可以將原來的陣列進行排序即可,直接隨機訪問到第K個元素即可。 我們專門寫一篇部落格當然不是想利用這種思路的,可以試試改進的快速排序啊,對不,我個人覺得是利用了兩種思路一個是快速排序一個是二分查詢,在進行快速排序的時候,在指定範圍內找
java 實現從無序陣列中 找出第k大的數, 無序陣列充許有重複元素
要求找出第幾名的元素是什麼(找出B[i]的值)? 找出第k名的元素的值。 先從A中隨機一個下標index1, 然後進行一趟快速排序等到新陣列A1,排完了就知道index1對應的元素在A1中的新下標index2. 如果k等於index2,則A1[index2]就是要找的值。 如果 k小於in
Day06--陣列中的第K個最大元素
class Solution: def findKthLargest(self, nums, k): """ :type nums: List[int] :type k: int :rtype: int
leetcode 215. 陣列中的第K個最大元素(Medium)(陣列)
題目: 在未排序的陣列中找到第 k 個最大的元素。請注意,你需要找的是陣列排序後的第 k 個最大的元素,而不是第 k 個不同的元素。 示例 1: 輸入: [3,2,1,5,6,4] 和 k = 2 輸出: 5 示例 2: 輸入: [3,2,3,1,
LeetCode 215——陣列中的第 K 個最大元素
1. 題目 在未排序的陣列中找到第 k 個最大的元素。請注意,你需要找的是陣列排序後的第 k 個最大的元素,而不是第 k 個不同的元素。 示例 1: 輸入: [3,2,1,5,6,4] 和 k = 2 輸出: 5 示例 2: 輸入: [3,
LeetCode題解 | 215. 陣列中的第K個最大元素
在未排序的陣列中找到第 k 個最大的元素。請注意,你需要找的是陣列排序後的第 k 個最大的元素,而不是第 k 個不同的元素。 示例 1: 輸入: [3,2,1,5,6,4] 和 k = 2 輸出: 5 示例 2: 輸入: [3,2,3,1,2,4,5,5,6] 和 k = 4 輸出: 4 說明:
LeetCode 215. 陣列中的第K個最大元素 Kth Largest Element in an Array
題目描述:就是在陣列中找到第k大的數 (1)第一種方法就是利用sort函式排序 時間複雜度 O(NlogN),空間複雜度 O(1) public int findKthLargest(int[] nums, int k) { Arrays.sort(nums); r
【LeetCode】215. 陣列中的第K個最大元素 結題報告 (C++)
原題地址:https://leetcode-cn.com/problems/kth-largest-element-in-an-array/submissions/ 題目描述: 在未排序的陣列中找到第 k 個最大的元素。請注意,你需要找的是陣列排序後的第 k 個最大的元素,而不是第 k 個不
leetcode 215 陣列中的第k個最大的元素
在未排序的陣列中找到第 k 個最大的元素。請注意,你需要找的是陣列排序後的第 k 個最大的元素,而不是第 k 個不同的元素。 示例 1:輸入: [3,2,1,5,6,4] 和 k = 2 輸出: 5示例 2:輸入: [3,2,3,1,2,4,5
Leetcode---陣列中的第K個最大元素--隨機化演算法
陣列中的第K個最大元素 題目連結:陣列中的第K個最大元素 思路: 如果先排序,不管利用哪個,比較排序時間複雜度最優為O(nlgn) 但是我們發現,快排的一趟排列有一定的性質,我們可以求得一趟快排之後,該數在整個陣列中排在第幾位,且將整個陣列劃分為兩段 利用這個
LeetCode 215. 陣列中的第K個最大元素 Python3
在未排序的陣列中找到第 k 個最大的元素。請注意,你需要找的是陣列排序後的第 k 個最大的元素,而不是第 k 個不同的元素。 示例 1: 輸入: [3,2,1,5,6,4] 和 k = 2 輸出: 5
陣列中的第K個最大元素
在未排序的陣列中找到第 k 個最大的元素。請注意,你需要找的是陣列排序後的第 k 個最大的元素,而不是第 k 個不同的元素。 示例 1: 輸入: [3,2,1,5,6,4] 和 k = 2 輸出:
陣列中的第K個最大元素 【LeetCode 排序】
在未排序的陣列中找到第 k 個最大的元素。請注意,你需要找的是陣列排序後的第 k 個最大的元素,而不是第 k 個不同的元素。 示例 1: 輸入: [3,2,1,5,6,4] 和 k = 2輸出: 5 示例 2: 輸入: [3,2,3,1,2,4,5,5,6] 和 k
LeetCode-215. 陣列中的第K個最大元素
題目 在未排序的陣列中找到第 k 個最大的元素。請注意,你需要找的是陣列排序後的第 k 個最大的元素,而不是第 k 個不同的元素。 示例 1: 輸入: [3,2,1,5,6,4] 和 k = 2 輸出: 5 示例 2: 輸入: [3,2,3,1,2,4,5,5,6]