leetcode215---Kth Largest Element in an Array(第k大元素)

来源:互联网 发布:哪个贷款软件最靠谱 编辑:程序博客网 时间:2024/05/16 16:13

问题描述:

Find the kth largest element in an unsorted array. Note that it is the kth largest element in the sorted order, not the kth distinct element.

For example,

Given [3,2,1,5,6,4] and k = 2, return 5.

Note:
You may assume k is always valid, 1 ≤ k ≤ array’s length.

问题求解:

方法一:利用快排的思想,使用快速选择算法(QuickSelect),时间复杂度为O(N).

class Solution {public:    int findKthLargest(vector<int>& nums, int k) {        int n=nums.size();        vector<int> left;        vector<int> right;        int key=nums[0];//(1)将nums[0]设置为主元,以此划分左右两部分        for(int i=1;i<n;i++)        {            if(nums[i] > key)            {//(2)大于key的放右边                right.push_back(nums[i]);            }            else if(nums[i] < key)            {//(3)小于key的放左边                left.push_back(nums[i]);            }        }        int nr=right.size();        int nl=left.size();        if(k <= nr)        {//(4)k<=nr则直接在右边找            return findKthLargest(right, k);        }        if(k > n-nl)        {//(5)k>n-nl则需在左边找k-(n-nl)个            return findKthLargest(left, k-(n-nl));        }        return key;//(6)主元即是第k大    }};

进一步,优化空间复杂度到O(1),代码如下:

class Solution {public:    int findKthLargest(vector<int>& nums, int k) {        int L = 0, R = nums.size() - 1;        while (L < R) {            int left = L, right = R;            int key = nums[left];//(1)主元            while (left < right) {                //(2)将大于key的放左边                while (left < right && nums[right] < key) --right;                nums[left] = nums[right];                //(3)将小于key的放右边                while (left < right && nums[left] >= key) ++left;                nums[right] = nums[left];            }            nums[left] = key;            if (left == k - 1) return nums[k - 1];            else if (left > k - 1) R = left - 1;//(4)更新R            else L = left + 1;//(5)更新L        }        return nums[k - 1];    }};

方法二:先排序再选择。时间复杂度:O(N*logN),空间复杂度:O(1)。

class Solution {public:    int findKthLargest(vector<int>& nums, int k) {        sort(nums.begin(), nums.end());//(1)排序        return nums[nums.size() - k];//(2)找到第k大元素    }};

方法三:建立大顶堆。make_heap()默认生成的是大顶堆,该函数接受两个随机迭代器,分别表示first,end,区间范围。也可通过自定义的cmp来生成小顶堆。

pop_heap() 首元素和末元素交换,再重新堆排序。 pop_back() 删除容器中最后一个元素。

代码:

class Solution {public:    int findKthLargest(vector<int>& nums, int k) {        make_heap(nums.begin(), nums.end());//(1)生成大顶堆        for(int i=0; i<k-1;i++)         {//弹出k-1个            //(2)把堆顶元素取出来,放到数组或者是vector的末尾,用原来末尾元素去替代            //然后end迭代器减1,执行siftdown()下溯函数来重新调整堆序。            //执行完毕后,最大的元素并没有被取走,而是放于底层容器的末尾。            pop_heap(nums.begin(), nums.end());            //(3)若要取走,可使用pop_back()函数。            nums.pop_back();        }        return nums.front();//(4)得到第k个大的    }};
0 0
原创粉丝点击