Sort-leetcode "Sort"

Source: Internet
Author: User

215. Kth largest Element in an Array4 C + + Solutions using Partition, Max-heap, Priority_queue and Multiset respectively

Well, this problem have a naive solution, which is to sort the array in descending order and return the k-1 -th element.

class Solution {public:    int findKthLargest(vector<int>& nums, int k) { sort(nums.begin(), nums.end()); return nums[k - 1]; }}; 

However, sorting algorithm gives O(nlogn) complexity. Suppose n = 10000 k = 2 and, then we is doing a lot of unnecessary operations. In fact, this problem have at least and faster solutions.

Well, the faster solution has no mystery. It is also closely related to sorting. I'll give II algorithms for this problem below, one using quicksort (specifically, the Partition subroutine) and the Oth Er using Heapsort.

Quicksort

In Quicksort, with each iteration, we need to select a pivot and then partition the array into three parts:

    1. Elements smaller than the pivot;
    2. Elements equal to the pivot;
    3. Elements larger than the pivot.

Now, let's do a example with the array in the [3, 2, 1, 5, 4, 6] problem statement. Let's assume in each time we select the leftmost element to is the pivot, in this case, 3 . We then use it to partition the array into the above 3 parts, which results in [1, 2, 3, 5, 4, 6] . Now are in the 3 third position and we know, it is the third smallest element. Now, does you recognize so this subroutine can is used to solve this problem?

In fact, the above partition puts elements smaller than the pivot before the pivot and thus the pivot would then be thek-th smallest element If it is in thek-1-th position. Since the problem requires us to find thek-th largest element, we can simply modify the partition to put elements larger than the pivot before the pivot. That's, after partition, the array becomes[5, 6, 4, 3, 1, 2]. Now we know that3is the4-th largest element. If we are asked to find the2-th largest element, then we know it's left to3. If we are asked to find the5-th largest element, then we know it's right to3. So, in the average sense, the problem are reduced to approximately half of its original size, giving the recursionT(n) = T(n/2) + O(n)in whichO(n)is the time for partition. This recursion, once solved, givesT(n) = O(n)And thus we have a linear time solution. Note that since we have need to consider one half of the array, the time complexity isO(n). If we need to consider both the halves of the arrays, like quicksort and then the recursion would beT(n) = 2T(n/2) + O(n)And the complexity would beO(nlogn).

Of course, is the O(n) average time complexity. In the worst case, the recursion may become and the T(n) = T(n - 1) + O(n) complexity would be O(n^2) .

Now let's briefly write down the algorithm before writing our codes.

    1. Initialize to being 0 and to is left right nums.size() - 1 ;
    2. Partition the array, if the pivot is k-1 at the-th position, return it (we were done);
    3. If k-1 The pivot is right-to-the-th position, update to being the left neighbor of the right pivot;
    4. Else update to being the right neighbor of the left pivot.
    5. Repeat 2.

Now let's turn it into code.

Class Solution {Publicint partition (vector<int>& Nums,IntLeftIntright) {int pivot = nums[Left];int L =Left +1, R =Rightwhile (L <= R) {if (Nums[l] < pivot && Nums[r] > Pivot) swap (nums[l++], nums[r--]);if (Nums[l] >= pivot) l++;if (Nums[r] <= pivot) r--; } Swap (nums[Left], nums[r]); return R; }int Findkthlargest (vector<int>& nums, int k) { int left = 0, right = Nums.size ()- 1; while (true) { Int. pos = partition (Nums, left , right ); if (pos = = k- 1) return Nums[pos]; if (pos > K- 1) Right = pos- 1; Else Left = pos + 1;             }}; 

Heapsort

Well, this problem still have a tag "heap". If you is familiar with heapsort, you can solve this problem using the following idea:

    1. Build a max-heap nums for, set to is heap_size nums.size() ;
    2. Swap nums[0] (after buding the max-heap, it'll be is the largest element) with nums[heap_size - 1] (currently the last element). Then decrease by heap_size 1 and max-heapify nums (recovering it max-heap property) at index 0 ;
    3. Repeat 2 for Times and the k k -th largest element would be a stored finally at nums[heap_size] .

Now I paste my code below. If you find it tricky, I suggest your to read the Heapsort chapter of Introduction to algorithms, which have a nice explanat Ion of the algorithm. My code simply translates the pseudo code in this book:-)

Class Solution {PublicInlineIntLeft(int idx) {Return (IDX <<1) +1; }InlineIntRight(int idx) {Return (IDX <<1) +2; }voidMax_heapify(vector<int>& Nums,int idx) {int largest = IDX;int L = Left (idx), R = Right (IDX);if (L < heap_size && Nums[l] > nums[largest]) largest = l;if (R < heap_size && Nums[r] > nums[largest]) largest = R;if (Largest! = idx) {swap (Nums[idx], nums[largest]); max_heapify (nums, largest);}}voidBuild_max_heap(vector<int>& nums) {heap_size = Nums.size ();for (int i = (heap_size >> 1)-1; i >= 0; i--) max_heapify (nums, i); } int findkthlargest (vector<int>& nums, int k" {build_max_heap (nums); for (int i = 0; i < K; i++) {Swap ( Nums[0], nums[heap_size-1]); heap_size--; Max_heapify (Nums, Span class= "Hljs-number" >0); } return nums[heap_size];} private: int heap_size;}       

If We is allowed to use the built-in  priority_queue , the code would be a much more shorter:-)

 class solution {public: int  Findkthlargest (vector<int>& nums, int k" {priority_queue<int> PQ (nums.begin (), Nums. End (for (int i = 0; i < K-1; i++) Pq.pop (); return pq.top ();}};  

Well, the  priority_queue  can also be replaced by  multiset  :-)

class Solution {public:    int findKthLargest(vector<int>& nums, int k) { multiset<int> mset; int n = nums.size(); for (int i = 0; i < n; i++) { mset.insert(nums[i]); if (mset.size() > k) mset.erase(mset.begin()); } return *mset.begin(); }};

Sort-leetcode "Sort"

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.