leetcode-215-数组中的第K个最大元素*

题目描述:

方法一:堆排序*

class Solution:
    def findKthLargest(self, nums: List[int], k: int) -> int:
        def adjust_heap(idx, max_len):
            left = 2 * idx + 1
            right = 2 * idx + 2
            max_loc = idx
            if left < max_len and nums[max_loc] < nums[left]:
                max_loc = left
            if right < max_len and nums[max_loc] < nums[right]:
                max_loc = right
            if max_loc != idx:
                nums[idx], nums[max_loc] = nums[max_loc], nums[idx]
                adjust_heap(max_loc, max_len)
        
        # 建堆
        n = len(nums)
        for i in range(n // 2 - 1, -1, -1):
            adjust_heap(i, n)
        #print(nums)
        res = None
        for i in range(1, k + 1):
            #print(nums)
            res = nums[0]
            nums[0], nums[-i] = nums[-i], nums[0]
            adjust_heap(0, n - i)
        return res

 

class Solution:
    def findKthLargest(self, nums: List[int], k: int) -> int:
        return heapq.nlargest(k, nums)[-1]

 

方法二:快速排序

class Solution:
    def findKthLargest(self, nums: List[int], k: int) -> int:
        def partition(left, right):
            pivot = nums[left]
            l = left + 1
            r = right
            while l <= r:
                if nums[l] < pivot and nums[r] > pivot:
                    nums[l], nums[r] = nums[r], nums[l]
                if nums[l] >= pivot:
                    l += 1
                if nums[r] <= pivot:
                    r -= 1
            nums[r], nums[left] = nums[left], nums[r]
            return r
        left = 0
        right = len(nums) - 1
        while 1:
            idx = partition(left, right)
            if idx == k - 1:
                return nums[idx]
            if idx < k - 1:
                left = idx + 1
            if idx > k - 1:
                right = idx - 1

 

方法三:bfprt算法*

class Solution:
    def findKthLargest(self, nums, k):
        index=self.BFPRT(nums, 0, len(nums) - 1, len(nums) - k + 1)
        return nums[index]

    def BFPRT(self, nums, l, r, k) :
        if l==r:
            return l
        pivot_index = self.getPivotIndex(nums, l, r)
        divide_index = self.partion(nums, l, r, pivot_index)
        num = divide_index - l + 1  # 当前的pivot是当前范围内排名第几小的
        if k == num:
            return divide_index
        elif num > k:
            return self.BFPRT(nums, l, divide_index - 1, k)
        else:
            return self.BFPRT(nums, divide_index + 1, r, k - num)

    def getPivotIndex(self, nums, l, r):
        if (r - l < 5):
            return self.insertSort(nums, l, r)
        tmp = l
        for i in range(l, r, 5):
            if i+4>r:
                break
            index = self.insertSort(nums, i, i + 4)  # 获取每个组的中位数索引
            nums[tmp], nums[index] = nums[index], nums[tmp]  # 将每个组的中位数放置在数组的左端
            tmp = tmp + 1
        return self.BFPRT(nums, l, tmp - 1, (tmp - 1 - l) // 2 + 1)  # 获取这几个中位数的中位数

    def insertSort(self, nums, l, r):  # 插入排序
        for i in range(l + 1, r + 1):
            tmp = nums[i]
            j = i - 1
            while j >= l and nums[j] > tmp:
                nums[j + 1] = nums[j]
                j -= 1
            nums[j + 1] = tmp
        return (r + l) // 2   # 返回的是索引

    def partion(self, nums, l, r, pivot_index):
        nums[l], nums[pivot_index] = nums[pivot_index], nums[l]  # 交换至最左侧
        pivot = nums[l]
        i, j = l, r
        while i < j:
            while i<r and nums[i] <= pivot:
                i += 1
            while l<j and nums[j] >= pivot:
                j -= 1
            if i < j:
                nums[i], nums[j] = nums[j], nums[i]
        nums[j], nums[l] = nums[l], nums[j]
        return j

 

posted @ 2019-10-03 16:20  oldby  阅读(150)  评论(0编辑  收藏  举报