1. 程式人生 > >215. Kth Largest Element in an Array(python+cpp)

215. Kth Largest Element in an Array(python+cpp)

題目:

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.
Example 1:

Input: [3,2,1,5,6,4] and k = 2 
Output: 5 

Example 2:

Input: [3,2,3,1,2,4,5,5,6] and k = 4 
Output: 4 

Note: You may assumek

is always valid, 1 ≤ k ≤ array's length.

解釋:
返回陣列中第k個最大元素,也就是陣列升序排序後,從右往左數的第k個數字(k從1開始),與第k大的數(排序後從左往右數,k從0開始)意義不同。
解法1,排序後返回,速度很快:

class Solution(object):
    def findKthLargest(self, nums, k):
        """
        :type nums: List[int]
        :type k: int
        :rtype: int
        """
        return
sorted(nums,reverse=True)[k-1]

解法2:分治思想,用partition做,按理說速度應該很快才對為什麼這麼慢…(我記得在牛客網上用python實現第k大的數最後超時了),劍指offer上是說一般的排序演算法的時間複雜度是O(nlogn),然而用partition做時間複雜度必然是低於快速排序的,可能這裡是因為成熟語言的排序演算法用了和一般排序演算法不一樣的策略,所以速度更快。
python程式碼:

class Solution(object):
    def findKthLargest(self, nums, k):
        """
        :type nums: List[int]
        :type k: int
        :rtype: int
        """
def partition(nums,left,right): pivot=nums[left] while left<right: while left<right and nums[right]>=pivot: right-=1 nums[left]=nums[right] while left<right and nums[left]<=pivot: left+=1 nums[right]=nums[left] nums[left]=pivot return left if k<0 or k>len(nums): return left=0 right=len(nums)-1 mid=partition(nums,left,right) key=len(nums)-k while mid!=key: if mid<key: mid=partition(nums,mid+1,right) else: mid=partition(nums,left,mid-1) return nums[mid]

c++程式碼:

class Solution {
public:
    int findKthLargest(vector<int>& nums, int k) {
        int n=nums.size();
        int left=0,right=n-1;
        int key=n-k;
        int mid=partition(nums,left,right);
        while (mid!=key)
        {
            if(mid>key)
                mid=partition(nums,left,mid-1);
            else
                mid=partition(nums,mid+1,right);
        }
        return nums[mid];
    }
    int  partition(vector<int>&nums,int left,int right)
    {
        int pivot=nums[left];
        while (left<right)
        {
            while(left<right && nums[right]>=pivot)
                right--;
            nums[left]=nums[right];
            while(left<right && nums[left]<=pivot)
                left++;
            nums[right]=nums[left];
        }
        nums[left]=pivot;
        return left;
    }
};

解法3:使用堆排序,速度相當快。

import heapq
class Solution(object):
    def findKthLargest(self, nums, k):
        """
        :type nums: List[int]
        :type k: int
        :rtype: int
        """
        return heapq.nlargest(k,nums)[-1];

總結
python的heapq這個庫完美地解決了top-K問題。
Python heapq模組常用函式複習:
1.heapq.heappush(heap, item) 把item新增到heap中(heap是一個列表)
2.heapq.heappop(heap) 把堆頂元素彈出,返回的就是堆頂
3.heapq.heappushpop(heap, item) 先把item加入到堆中,然後再pop,比 heappush()heappop() 要快得多
4.heapq.heapreplace(heap, item) 先pop,然後再把item加入到堆中,比 heappop()heappush() 要快得多
5.heapq.heapify(x)列表x進行堆調整,預設的是小頂堆
6.heapq.merge(*iterables) 將多個列表合併,並進行堆調整,返回的是合併後的列表的迭代器
7.heapq.nlargest(n, iterable, key=None) 返回最大的n個元素,是個列表 list,從大到小排序(Top-K問題)
8.heapq.nsmallest(n, iterable, key=None)返回最小的n個元素,是個列表 list,從小到大排序(Top-K問題)

c++的heap不好用,不說了。