最小の数Kは、安全性を証明しますOffer--

1.トピック

2.回答

2.1方法1 - ヒープビッグトップ

参考ヒープとソート・ヒープアプリケーション・ヒープ、我々は最初のトップの大きなヒープとしてKの配列位置。

第即ちスタックの上部からノード[(K-2)/ 2、0]を積層し、スタックを構築します。最初のK / 2のノードは、子ノードの場合、その左の子ノード位置2は、明らかに最初のK / 2のノードはK / 2 + 1 = K + 1、我々はK-1の山最大位置である*なければなりません最初のリーフノードではなく、山の。

現在の要素の要素はスタックの最上部よりも小さい場合、スタックの構築が完了した後、我々は、要素の位置アクセス源アレイ[K、N-1]を逐次、スタック要素の上部を削除し、現在の要素をヒープに挿入され、要素の位置は0です。

最後に、K素子のヒープも望まれています。

class Solution {
public:
    vector<int> GetLeastNumbers_Solution(vector<int> input, int k) {
        
        if (k > input.size())
        {
            vector<int> result;
            return result;
        }
        Build_Heap_K(input, k);
        vector<int> result(input.begin(), input.begin()+k);
        return result;
    }
    
    void Build_Heap_K(vector<int> &input, int k)
    {
        // input 的 [0, k-1] 作为一个大小为 K 的大顶堆
        // 然后从上往下进行堆化
        // 也就是对堆中 [0, (k-2)/2] 的节点进行堆化
        for (int i = (k-2)/2; i >= 0; i--)
            Heapify(input, k, i);
        
        // 遍历 input 的 [k, n-1] 的元素
        // 如果某元素小于堆顶值,将其插入堆中
        // 也即将其替换为堆顶元素,堆化之
        for (int i = k; i < input.size(); i++)
        {
            if (input[i] < input[0])
            {
                input[0] = input[i];
                Heapify(input, k, 0);
            }
        }
    }
    
    void Heapify(vector<int> &input, int k, int i)
    {
        while(1)
        {
            int max_pos = i;
            if (2*i+1 < k && input[2*i+1] > input[max_pos])
                max_pos = 2 * i + 1;
            if (2*i+2 < k && input[2*i+2] > input[max_pos])
                max_pos = 2 * i + 2;
            if (max_pos == i)
                   break;
            else
            {
                int temp = input[max_pos];
                input[max_pos] = input[i];
                input[i] = temp;
            }
            i = max_pos;
        }
    }
};
2.2方法2 - 高速行パーティション

参照LeetCode 215--アレイK番目の最大要素

必要パーティション、左側素子のパーティション点が主エレメントよりも小さいクイックドレーンが、要素は、パーティションのピボット点の右よりも大きいです。もしKのちょうど最小数を左パーティション皇帝の元正確Kの位置、; Kより大きい場合、我々は再帰的に左のK番目の位置を見つける必要があり、K未満は、その後、我々は右再帰K番目を見つける必要がある場合場所。

class Solution {
public:
    vector<int> GetLeastNumbers_Solution(vector<int> input, int k) {
        int n = input.size();
        if (k > n)
        {
            vector<int> result;
            return result;
        }
        Quick_Sort(input, 0, n-1, k);
        vector<int> result(input.begin(), input.begin()+k);
        return result;
    }
    
    void Quick_Sort(vector<int> &input, int left, int right, int k)
    {
        if (left < right)
        {
            int pivot = input[right];
            int i = left;
            int j = left;
            
            for (; j < right; j++)
            {
                if (input[j] < pivot)
                {
                    int temp = input[i];
                    input[i] = input[j];
                    input[j] = temp;
                    i++;
                }
            }
            input[j] = input[i];
            input[i] = pivot;
            
            if (i == k)    return;
            else if (i > k)    Quick_Sort(input, left, i-1, k);
            else Quick_Sort(input, i+1, right, k);
        }
    }
};

よりエキサイティングについては、「seniusen」に注意を払ってください!

おすすめ

転載: www.cnblogs.com/seniusen/p/10935247.html