快速排序算法 数组中的第K个最大元素

215. 数组中的第K个最大元素

给定整数数组 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

思路:

  思路很简单,先对数组进行从大到小的排序,然后取排序后的第k个值就得到了第k个最大元素啦。

  像这种排序就占了几乎全部解题过程的题目,我们是不能直接使用sort()方法的。而自己写排序算法,最常见也是必须掌握的方法之一就是快速排序了。

  所以就借此题写一下快速排序的过程和思路,当我们可以把快速排序写出来后,这道题也就自然解决了。

快速排序思路:

  快速排序是采用递归的思路来实现的,因为是递归,所以我们单从最外层就可以明确它的思路。首先我们需要一个函数move_pivot(),该函数的作用就是对于一个数组,选择第一个数作为pivot(也可以选择随机的数,这个影响到快排的效率,取决于原数组具体是什么样的),然后将数组中比pivot小的数放到pivot的左边,比pivot大的数放在它的右边,并返回pivot的位置下标。

  这样,当我们从最外层调用一次这个函数的时候,我们就首先确定了pivot的正确位置,并且保证了它左边的都是比它小的,右边的都是比它大的。然后我们对于左边和右边的两段再分别调用这个函数,具体细节我们无需再管,递归就自动帮我们实现好排序了。

  那么,如何实现move_pivot()的具体功能呢?我们需要左右指针left和right,分别置于数组的左右两端。然后我们取出left——也就是第0个位置的值拿出并存到pivot,此时可以理解成left位置处为空了。接下来,在left<right的前提下,我们循环以下操作:

  当left为空时,将right逐步向左移动,如果right处值小于pivot,就说明它应该出现在pivot左边,就将其移动到空的left处,此时right处为空了;

  当right为空时,将left逐步向右移动,如果left处值大于pivot,就说明它应该出现在pivot右边,就将其移动到空的right处,此时left处又为空了。

  重复这两种操作,直到left于right相遇,此时只有一个位置被空了出来,也就是数组pivot应该存放的位置。在找个位置左边全是比pivot小的数;在这个位置右边全是比pivot大的数。

快速排序代码:

def kuaisupaixu(nums):

    def move_pivot(left,right,nums):

        pivot = nums[left]#刚开始,取left值为pivot,此时left相当于为“空”了

        while(left<right):#当左右指针没有相遇时

            while(nums[right]>=pivot and right>left):#右指针向左移动,直到找到比pivot小的值

                right-=1

            nums[left]=nums[right]#将这个值填到left坑中,此时right为“空”了

            while(nums[left]<=pivot and left<right):#左指针向右移动,直到找到比pivot大的值

                left+=1

            nums[right]=nums[left]#将这个值填到right中,此时left又为“空”了,又该右指针right移动了……

        nums[left]=pivot#当左右指针相遇时,相遇位置必然为“空”,这个位置就是pivot应该存放的位置

        return left

    def quick_sort(left,right,nums):#定义快速排序

        if left<right:#当左指针小于右指针时

            mid = move_pivot(left,right,nums)#先进行一次pivot的定位,并且对左右进行好处理

            #此时返回的mid就是pivot的位置

            quick_sort(left,mid-1,nums)#对pivot左边进行快排

            quick_sort(mid+1,right,nums)#对pivot右边进行快排

    left = 0#初始化左指针在最左边

    lenth = len(nums)

    right=lenth-1#初始化右指针在最右边

    quick_sort(left,right,nums)

  这道题解决代码:

class Solution(object):

    def findKthLargest(self, nums, k):

        nums.sort(reverse=True)

        return nums[k-1]

  嘿嘿,搞错了,是这个:

代码:

class Solution(object):

    def findKthLargest(self, nums, k):

        def move_pivot(left,right,nums):

            pivot = nums[left]#刚开始,取left值为pivot,此时left相当于为“空”了

            while(left<right):#当左右指针没有相遇时

                while(nums[right]>=pivot and right>left):#右指针向左移动,直到找到比pivot小的值

                    right-=1

                nums[left]=nums[right]#将这个值填到left坑中,此时right为“空”了

                while(nums[left]<=pivot and left<right):#左指针向右移动,直到找到比pivot大的值

                    left+=1

                nums[right]=nums[left]#将这个值填到right中,此时left又为“空”了,又该右指针right移动了……

            nums[left]=pivot#当左右指针相遇时,相遇位置必然为“空”,这个位置就是pivot应该存放的位置

            return left

        def quick_sort(left,right,nums):#定义快速排序

            if left<right:#当左指针小于右指针时

                mid = move_pivot(left,right,nums)#先进行一次pivot的定位,并且对左右进行好处理

                #此时返回的mid就是pivot的位置

                quick_sort(left,mid-1,nums)#对pivot左边进行快排

                quick_sort(mid+1,right,nums)#对pivot右边进行快排

        left = 0#初始化左指针在最左边

        lenth = len(nums)

        right=lenth-1#初始化右指针在最右边

        quick_sort(left,right,nums)

        return nums[lenth-k]#因为上面写的快排是从小到大排序的,所以是lenth-k,倒着数
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

JunanP

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值