トピック リンク: 215. 配列の K 番目に大きい要素 - LeetCode
質問の語幹:
整数配列 nums と整数 k を指定すると、配列内で k 番目に大きい要素を返します。
k 番目の個別の要素ではなく、ソートされた配列の k 番目に大きい要素を探していることに注意してください。
この問題を解決するには、時間計算量 O(n) のアルゴリズムを設計して実装する必要があります。
例 1:
入力: [3,2,1,5,6,4]、k = 2
出力: 5
例 2:入力: [3,2,3,1,2,4,5,5,6]、k = 4
出力: 4
トピック分析:
k 番目に大きいデータと上位 k 番目に大きいデータを見ると、2 つの解が考えられます
- ソートし、k 番目の位置の値を見つける
- 積み上げ
ここで、ソートを直接使用してこの質問を行うと、少しイライラしすぎて効率が低すぎるため、ヒープを構築することをお勧めします。デフォルトでは、大きなヒープが構築され、ヒープが構築された後の k 番目の pop の結果が、探している値です。
最適化:ここで, 配列全体がヒープを構築するために, 配列が大きくても k が小さい場合, 上記のソリューションの効率は十分に極端ではありません. このとき, 実際には k 要素の小さなヒープを構築することを検討できます.、そして配列全体をトラバースします.ヒープの一番上にある現在のデータと nums[i] のサイズを判断します. nums[i] の方が大きい場合は、ヒープの一番上のデータをポップしてから nums[i] を挿入します] をヒープに入れ、次にデータを配列に挿入します. トラバーサルが完了すると、配列全体が完了すると、最初のk 個の最大のデータが、構築したヒープにあり、このとき k 番目に大きい数字が at の要素ですヒープの一番上。この解の時間計算量は O(K+(NK)logK) です。
コード:
//解法一
class Solution {
public:
int findKthLargest(vector<int>& nums, int k) {
priority_queue<int> heap(nums.begin(), nums.end());
while(--k)
{
heap.pop();
}
return heap.top();
}
};
//优化
class Solution {
public:
int findKthLargest(vector<int>& nums, int k) {
priority_queue<int, vector<int>, greater<int>> heap(nums.begin(), nums.begin() + k);
for(size_t i = k; i < nums.size(); ++i)
{
if(nums[i] > heap.top())
{
heap.pop();
heap.push(nums[i]);
}
}
return heap.top();
}
};