
系列索引:【菜菜的刷题日记】被LeetCode用Python狂虐的那段日子
【题目】
给定整数数组 nums 和整数 k,请返回数组中第 k 个最大的元素。
请注意,你需要找的是数组排序后的第 k 个最大的元素,而不是第 k 个不同的元素。
- 标签:数组、堆排序
- 难度:中等
示例 1:
输入: [3,2,1,5,6,4] 和 k = 2
输出: 5
示例 2:
输入: [3,2,3,1,2,4,5,5,6] 和 k = 4
输出: 4
题目链接:https://leetcode-cn.com/problems/kth-largest-element-in-an-array/
【我的代码】
这效率真是。。Python在算法方面本身就不如c那么高效,加之我的水平不高,所以还是得多看看大佬们的代码学习学习,不过直接用sort这种就有点太那啥了吧 /wul
 
 主要是选择排序的思想。
class Solution:
    def findKthLargest(self, nums: List[int], k: int) -> int:
        for i in range(len(nums)-1, len(nums)-1-k, -1):
            m = i
            for j in range(i-1, -1, -1):
                if nums[j] > nums[m]:
                    m = j
            if m != i:
                nums[i], nums[m] = nums[m], nums[i]
        return nums[-k]
【参考代码1】暴力法
直接sort排序,不得不说这效率比我写的高多了。
 
 简单两行直接完事,NB(虽然锻炼不了数据结构等知识)我要是面试写这会不会…
class Solution:
    def findKthLargest(self, nums: List[int], k: int) -> int:
        nums.sort()
        return nums[-k]
【参考代码2】堆排序
升序堆排序的思路如下:
-  先建立 大顶堆
-  让堆顶最大元素与最后一个交换,然后调整第一个元素到倒数第二个元素,这一步获取最大值 
-  再交换堆顶元素与倒数第二个元素,然后调整第一个元素到倒数第三个元素,这一步获取第二大值 
-  以此类推,直到最后一个元素交换之后完毕。 
这道题我们只需进行 1 次建立大顶堆, k-1 次调整即可得到第 k 大的数。
时间复杂度:O(n2)
class Solution:
    def findKthLargest(self, nums: List[int], k: int) -> int:
        # 调整为大顶堆
        def heapify(nums, index, end):
            left = index * 2 + 1
            right = left + 1
            while left <= end:
                # 当前节点为非叶子节点
                max_index = index
                if nums[left] > nums[max_index]:
                    max_index = left
                if right <= end and nums[right] > nums[max_index]:
                    max_index = right
                if index == max_index:
                    # 如果不用交换,则说明已经交换结束
                    break
                nums[index], nums[max_index] = nums[max_index], nums[index]
                # 继续调整子树
                index = max_index
                left = index * 2 + 1
                right = left + 1
                
        # 初始化大顶堆
        def buildMaxHeap(nums):
            size = len(nums)
            # (size-2) // 2 是最后一个非叶节点,叶节点不用调整
            for i in range((size - 2) // 2, -1, -1):
                heapify(nums, i, size - 1)
            return nums
        buildMaxHeap(nums)
        size = len(nums)
        for i in range(k-1):
            nums[0], nums[size-i-1] = nums[size-i-1], nums[0]
            heapify(nums, 0, size-i-2)
        return nums[0]
        
【参考代码3】快速排序
快速排序每次调整,都会确定一个元素的最终位置,且以该元素为界限,将数组分成了两个数组,前一个数组元素都比该元素小,后一个元素都比该元素大。
这样,只要某次划分的元素恰好是第 k 个下标就找到了答案。并且我们只需关注 k 元素所在区间的排序情况,与 k 元素无关的区间排序都可以忽略。这样进一步减少了执行步骤。
import random
class Solution:
    def findKthLargest(self, nums: List[int], k: int) -> int:
        def randomPartition(nums, low, high):
            i = random.randint(low, high)
            nums[i], nums[high] = nums[high], nums[i]
            return partition(nums, low, high)
        def partition(nums, low, high):
            x = nums[high]
            i = low-1
            for j in range(low, high):
                if nums[j] <= nums[high]:
                    i += 1
                    nums[i], nums[j] = nums[j], nums[i]
            nums[i+1], nums[high] = nums[high], nums[i+1]
            return i+1
        def quickSort(nums, low, high, k):
            n = len(nums)
            if low < high:
                pi = randomPartition(nums, low, high)
                if pi == n-k:
                    return nums[len(nums)-k]
                if pi > n-k:
                    quickSort(nums, low, pi-1, k)
                if pi < n-k:
                    quickSort(nums, pi+1, high, k)
            return nums[len(nums)-k]
        return quickSort(nums, 0, len(nums)-1, k)
        
【思考】
一首《明日歌》送给大家,也希望自己能珍惜当下!










