The smallest number K prove safety Offer--

1. Topic

2. Answers

2.1 Method One - heap big top

Reference heap and sort heap and the application heap , we will first K array position as a top big heap.

First build stack, i.e. to stack [0, (K-2) / 2] of the node from the top of the stack. The first K / 2 nodes if a child node, its left child node position should be 2 * K / 2 + 1 = K + 1, and the maximum position we heap of K-1, apparently the first K / 2 nodes is The first leaf node, not of pile.

After completion of building the stack, we sequential access source array [k, n-1] positions of the elements, if the elements of the current element is less than the top of the stack is position 0 of the elements, then deleting the top of the stack element and the current element is inserted into the heap.

Finally, the heap of K elements is also desired.

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 Method Two - fast row partition

Refer LeetCode 215-- array K-th largest element .

Quick drain when the need partition, the partition point on the left element are smaller than the main element, the element is greater than the right of the pivot point of the partition. If the location of the partition emperor yuan exactly K, that left just the minimum number of K; if greater than K, we need to recursively find the K-th position on the left; if less than K, then we need to find the right recursion K-th position.

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);
        }
    }
};

For more exciting, please pay attention to "seniusen"!

Guess you like

Origin www.cnblogs.com/seniusen/p/10935247.html