赞
踩
给定整数数组 nums 和整数 k,请返回数组中第 k 个最大的元素。
请注意,你需要找的是数组排序后的第 k 个最大的元素,而不是第 k 个不同的元素。
输入: [3,2,1,5,6,4] 和 k = 2
输出: 5
方法1,先快速排序,再从前往后索引到第长度减k个最小元素,即第k个最大的元素。但是这种方法时间和空间复杂度太高,需要把全部元素都排序一遍,再索引。具体过程是先执行快排函数,第一步是让数组的第一个元素当基准,将它放在合适的位置,同时将数组分为基准左右两个部分,这两个部分在分别调用快排函数,直到左右指针相同,跳出循环,排序完成。
划分为两部分的函数具体过程:
将左指针的元素作为基准,然后认为将基准元素提取出来,开始遍历数组,左边指针空,遍历右边,如果右指针对应的数大于或者基准,不用移动,将右指针左移一位,如果右指针的元素小于基准,就将它的值给到左指针空的位置,左指针向右移动一位,现在右指针为空,这样依次遍历,让大于基准的数往右放,小于基准的数往左放,直到两个指针相同了,跳出循环,将基准这个数放到左指针的位置上,现在左指针的位置就是分成两段的中间位置,然后左右两部分再递归调用排序函数。
最后索引到数组中第k个最大的元素返回即可。
方法2,基于快速排序的选择方法
这个过程是递归调用快速选择函数,同样的用函数将数组分成两部分,这个过程优化了快排的步骤,这里在数组区间内随机选择一个数作为基准,然后将小于基准的数都放到基准前面,大于基准的数都放到基准后面,再将基准数放到中间的位置,这个位置就是它的正确位置,然后读取这个基准的索引,看它在我们要找的索引前面还是后面,如果在前面,那就将递归调用的区间设为后面,如果在后面,就将递归调用的区间设为前面,减少递归次数,如果这个索引正是我们要找到元素,直接返回结果即可。
这样随机化的时间复杂度是O(n),空间复杂度和递归调用的次数有关。
class Solution(object): def findKthLargest(self, nums, k): """ :type nums: List[int] :type k: int :rtype: int """ # 原始快排,太慢了 # def quicksort(nums,left,right): # if left < right: # pivotpos = partion(nums,left,right) # quicksort(nums,left,pivotpos-1) # quicksort(nums,pivotpos+1,right) # return nums # def partion(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 # length = len(nums) # left = 0 # right = length - 1 # quicksort(nums,left,right) # return nums[length-k] # 基于快速排序的选择方法 def quickselect(start,end,nums,k): if start == end: return nums[start] mid = partion(start,end,nums) if mid == len(nums)-k: return nums[mid] elif mid < len(nums)-k: return quickselect(mid+1,end,nums,k) elif mid > len(nums)-k: return quickselect(start,mid-1,nums,k) def partion(start,end,nums):# 随机选取,但要全部遍历到,所以这个区间范围内要全部移动好 p = random.randrange(start,end+1)# 随机选取的话,快排过程和前面不同 pivot = nums[p] nums[end],nums[p] = nums[p],nums[end] mid = start for i in range(start,end): if nums[i] <= pivot: nums[i],nums[mid] = nums[mid],nums[i] mid += 1 nums[mid],nums[end] = nums[end],nums[mid] return mid res = quickselect(0,len(nums)-1,nums,k) return res
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。