LeetCode 251. Kth Largest Element in an Array

    xiaoxiao2021-03-25  136

    本题要求在一个数组中找出第k大的元素, 比如在[3,2,1,5,6,4]中找第2大的元素,函数应该返回5。 本题至少可以使用O(nlogn)的排序算法来将数组排序,课上讲过一种更好的类似快排的做法,今天做一下实现:

    #include <vector> #include <cstdlib> #include <ctime> #include <utility> using namespace std; class Solution { public: int findKthLargest(vector<int>& nums, int k) { vector<int>::iterator begin = nums.begin(); vector<int>::iterator end = nums.end(); srand(time(NULL)); return findKthLargest1(begin, end, k); } int findKthLargest1(vector<int>::iterator begin, vector<int>::iterator end, int k) { if (begin >= end) return *begin; unsigned int idx = rand() % (end - begin); swap(*begin, *(begin + idx)); vector<int>::iterator r = begin, l = end - 1; int key = *begin; while (r < l) { while (key <= *l && l > r) l--; swap(*r, *l); while (key >= *r && r < l) r++; swap(*r, *l); } int larger_count = end - l; if (larger_count == k) return *l; else if (larger_count > k) return findKthLargest1(r + 1, end, k); else // larger_count < k return findKthLargest1(begin, l, k - larger_count); } };

    这里使用了分治思想,采用递归来实现该算法,当然也可以使用循环来实现。这里的实现是一个随机算法,首先在数组中随机找到一个数,将它与数组首个元素交换,然后使用快排中的划分方法,以矩阵首元素为key,将矩阵分为[ [小于key], key, [大于key]]3部分,然后就可以得知key是第larger_count大的数,若larger_count等于k就返回,否则根据larger_count和k的关系来决定在[小于key]中寻找,或在[大于key]中寻找。 这个算法的期望复杂度为O(n),如果能在O(n)时间内找到的话则一定是这个问题最快的方法,但是这是一个随机算法,其最坏的复杂度为O(n^2),总的来说,这种方法优于基于排序的O(nlogn)的方法。

    转载请注明原文地址: https://ju.6miu.com/read-798.html

    最新回复(0)