【Leetcode/解题报告】 215. Kth Largest Element in an Array

    给定一个未排序的数组,求其中第k大数。

    用分治法的思想,每次从数组中随便取一个数p,将所有大于p的数放在p的左边,其余数放在p的右边,记最终p在数组中的下标为i,则p为数组的第i+1大的数。

    若i+1 == k,第k大数即为p,算法结束。

    若i+1 < k,第k大数在p的右边,继续在p的右边的数组找第k - i - 1大数。

    若i + 1 > k,第k大数在p的左边,继续在p的左边数组找第k大数。

    第一个版本我开了额外的数组分别保存比p大和比p小的数,这样的代码简洁且易于理解,但会超空间限制。

class Solution(object):
	def findKthLargest(self, nums, k):
		"""
		:type nums: List[int]
		:type k: int
		:rtype: int
		"""
		pivot = nums[0]
		small = [i for i in nums[1:] if i <= pivot]
		large = [i for i in nums[1:] if i > pivot]
		if len(large) + 1 == k: return pivot
		elif len(large) + 1 < k: return self.findKthLargest(small, k - len(large) - 1)
		else: return self.findKthLargest(large, k) 
    要不使用额外空间,只能修改原来的数组。
class Solution(object):
	def findKthLargest(self, nums, k):
		"""
		:type nums: List[int]
		:type k: int
		:rtype: int
		"""
		return self.findK(nums, 0, k, len(nums))

	def findK(self, nums, start, k, end):
		pivot = nums[start]
		last_big = start                         # 最后一个比p大的数的下标
		for i in range(start + 1, end):
			if nums[i] > pivot:
				last_big += 1
				nums[last_big], nums[i] = nums[i], nums[last_big]
		nums[last_big], nums[start] = nums[start], nums[last_big]      # last_big变为p的下标
		if last_big + 1 == k: return pivot
		elif last_big + 1 > k: return self.findK(nums, start, k, last_big)
		else: return self.findK(nums, last_big + 1, k, end)                  # 注意k是不用改变的 


猜你喜欢

转载自blog.csdn.net/weixin_38196217/article/details/80092346