菜菜的刷题日记 | 215. 数组中的第K个最大元素

news/2024/7/4 13:25:03 标签: leetcode, 排序算法, 算法, 后端, python

请添加图片描述

系列索引:菜菜的刷题日记 | 被LeetCode用Python狂虐的那段日子

菜鸡的修仙之路——2022/1/17
这两天虽然没写题解博客不过每天一道依然没有断,只是写的简单题有时候觉得没写的必要。

文章目录

    • 【题目】
    • 【我的代码】
    • 【参考代码1】暴力法
    • 【参考代码2】堆排序
    • 【参考代码3】快速排序
    • 【思考】

【题目】

给定整数数组 nums 和整数 k,请返回数组中第 k 个最大的元素。

请注意,你需要找的是数组排序后的第 k 个最大的元素,而不是第 k 个不同的元素。

  • 标签:数组、堆排序
  • 难度:中等
python">示例 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
在这里插入图片描述
主要是选择排序的思想。

python">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(虽然锻炼不了数据结构等知识)我要是面试写这会不会…

python">class Solution:
    def findKthLargest(self, nums: List[int], k: int) -> int:
        nums.sort()
        return nums[-k]

【参考代码2】堆排序

升序堆排序的思路如下:

  1. 先建立大顶堆

  2. 让堆顶最大元素与最后一个交换,然后调整第一个元素到倒数第二个元素,这一步获取最大值

  3. 再交换堆顶元素与倒数第二个元素,然后调整第一个元素到倒数第三个元素,这一步获取第二大值

  4. 以此类推,直到最后一个元素交换之后完毕。

这道题我们只需进行 1 次建立大顶堆, k-1 次调整即可得到第 k 大的数。

时间复杂度:O(n2)

python">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 元素无关的区间排序都可以忽略。这样进一步减少了执行步骤。

python">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)
        

【思考】

一首《明日歌》送给大家,也希望自己能珍惜当下!

明日复明日,明日何其多。
我生待明日,万事成蹉跎。
世人苦被明日累,春去秋来老将至。
朝看水东流,暮看日西坠。
百年明日能几何?请君听我明日歌。
明日复明日,明日何其多!
日日待明日,万事成蹉跎。
世人皆被明日累,明日无穷老将至。
晨昏滚滚水东流,今古悠悠日西坠。
百年明日能几何?请君听我明日歌。

Python力扣题解系列持续更新,欢迎点赞收藏关注

上一篇:菜菜的刷题日记 | 118.杨辉三角
下一篇:菜菜的刷题日记 | 374.猜数字大小

本人水平有限,文章中不足之处欢迎下方👇评论区批评指正~

如果感觉对你有帮助,点个赞👍 支持一下吧 ~

不定期分享 有趣、有料、有营养内容,欢迎 订阅关注 🤝 我的博客 ,期待在这与你相遇 ~


http://www.niftyadmin.cn/n/1425835.html

相关文章

使用CVS进行版本控制实战 svn

http://www.dezai.cn/Article_Show.asp?ArticleID21269&ArticlePage2 svn好用一些吗

菜菜的刷题日记 | 猜数字?我还真猜不到(力扣374)

系列索引&#xff1a;菜菜的刷题日记 | 被LeetCode用Python狂虐的那段日子 菜菜的修仙之路——2022/1/18 今晚看了一会儿数据结构排序算法&#xff0c;发现之前对排序掌握的并不是很全面&#xff0c;像希尔这种都不会写&#xff0c;白天出门了&#xff0c;又是摆烂的一天。 文章…

菜菜的Python学习日记 | 正则表达式你必须了解的知识点

系列索引&#xff1a;菜菜的Python学习日记 | Python从入门到入土详解 文章目录常用规则Python对正则表达式的支持常用规则 符号解释示例说明.匹配任意字符b.t可以匹配bat / but / b#t / b1t等\w匹配字母/数字/下划线b\wt可以匹配bat / b1t / b_t等但不能匹配b#t\s匹配空白字符…

修改带图片的

修改带图片的先显示原先的图片(hidden src"取数据库中的") String src su.getRequest().getParameter("src"); com.jspsmart.upload.File myFile su.getFiles().getFile(0); String img myFile.getFileName(); String imgname su.getRequest().get…

菜菜的Python学习日记 | 多进程和多线程详解

系列索引&#xff1a;菜菜的Python学习日记 | Python从入门到入土详解 今天我们使用的计算机早已进入多CPU或多核时代&#xff0c;而我们使用的操作系统都是支持“多任务”的操作系统&#xff0c;这使得我们可以同时运行多个程序&#xff0c;也可以将一个程序分解为若干个相对独…

程序中下载限速如何实现

应该是在服务器上控制吧。 每个用户连接时记录开始时间&#xff0c;通信时记录已传输数量。 已传输数量除通信连接时间就是速率。 用timer定时扫描每个连接&#xff0c;如果发现某用户速率过大&#xff0c;在接收或者发送数据时加sleep延迟。。 try{Thread…

菜菜的刷题日记 | 1629. 按键持续时间最长的键

系列索引&#xff1a;菜菜的刷题日记 | 被LeetCode用Python狂虐的那段日子 菜菜的修仙之路——2022/1/19 又是摆烂的一天。 文章目录【题目】【我的代码】【思考】【题目】 难度&#xff1a;简单 题目链接&#xff1a;https://leetcode-cn.com/problems/slowest-key/ 【我的代…

菜菜的Python学习日记 | 蓝桥杯2021年第十二届省赛真题-双向排序

系列索引&#xff1a;菜菜的Python学习日记 | Python从入门到入土详解 今天写了道蓝桥杯真题&#xff0c;题并不难&#xff0c;但是要输入数据&#xff0c;这和以往的题目还不太一样&#xff0c;需要以空格作为结尾。而input函数输入的一个字符串&#xff0c;因此需要对输入值进…