LeetCode Python题解(二)----排序

根据: githhub优秀创作者.

算法思想

1.双指针法
2.排序
3.贪心思想
4.二分查找
5.分冶
6.搜索
7.动态规划
8.数学

快速排序

用于求解 Kth Element 问题,也就是第 K 个元素的问题。

可以使用快速排序的 partition() 进行实现。需要先打乱数组,否则最坏情况下时间复杂度为 O(N2 )。

用于求解 TopK Elements 问题,也就是 K 个最小元素的问题。可以维护一个大小为 K 的最小堆,最小堆中的元素就是最小元素。最小堆需要使用大顶堆来实现,大顶堆表示堆顶元素是堆中最大元素。这是因为我们要得到 k 个最小的元素,因此当遍历到一个新的元素时,需要知道这个新元素是否比堆中最大的元素更小,更小的话就把堆中最大元素去除,并将新元素添加到堆中。所以我们需要很容易得到最大元素并移除最大元素,大顶堆就能很好满足这个要求。

堆也可以用于求解 Kth Element 问题,得到了大小为 k 的最小堆之后,因为使用了大顶堆来实现,因此堆顶元素就是第 k 大的元素。

快速选择也可以求解 TopK Elements 问题,因为找到 Kth Element 之后,再遍历一次数组,所有小于等于 Kth Element 的元素都是 TopK Elements。

可以看到,快速选择和堆排序都可以求解 Kth Element 和 TopK Elements 问题。

1.数组中的第K个最大元素(215题)

题目描述:找到倒数第 k 个的元素。

输入: [3,2,1,5,6,4] 和 k = 2
输出: 5

1.1 排序:排序 :时间复杂度 O(NlogN),空间复杂度 O(1)

class Solution:
	def findKthLargest(self,nums,k):
		nums.sort()
		return nums[-k]

1.2 快速选择 :时间复杂度 O(N),空间复杂度 O(1)

思路:先使用快速排序的方法,再选出第K大的值

  • 快排思想为选出一个基数,并且把基数的左右划分为两部分
  • 再把左边部分进行二次快排
  • 把右边进行二次快排
class Solution:
	def findKthLargest(self,nums,k):
		k = len(nums)-k
		self.quicksort(nums,0,len(nums)-1)
		return nums[k]

	def parttion(self,v, left, right):              //划分
		key = v[left]
		low = left
		high = right
		while low < high:
			while (low < high) and (v[high] >= key):
				high -= 1
			v[low] = v[high]
			while (low < high) and (v[low] <= key):
				low += 1
			v[high] = v[low]
			v[low] = key
		return low


	def quicksort(self,v, left, right):
		if left < right:
			p = self.parttion(v, left, right)    //选出基数
			self.quicksort(v, left, p-1)     //左边快排
			self.quicksort(v, p+1, right)     //右边快排
		return v
荷兰国旗问题

荷兰国旗包含三种颜色:红、白、蓝。

有三种颜色的球,算法的目标是将这三种球按颜色顺序正确地排列。它其实是三向切分快速排序的一种变种,在三向切分快速排序中,每次切分都将数组分成三个区间:小于切分元素、等于切分元素、大于切分元素,而该算法是将数组分成三个区间:等于红色、等于白色、等于蓝色。

Alt

按颜色进行排序

题目描述:给定一个包含红色、白色和蓝色,一共 n 个元素的数组,原地对它们进行排序,使得相同颜色的元素相邻,并按照红色、白色、蓝色顺序排列。

输入: [2,0,2,1,1,0]
输出: [0,0,1,1,2,2]
class Solution:
	def sortColors(self,nums):
		zero,one,two = -1,0,len(nums)
		while one < two:
			if nums[one] == 0:
				zero += 1
				nums[zero],nums[one] = nums[one],nums[zero]
				one += 1
			elif nums[one] == 2:
				two -= 1
				nums[two],nums[one] = nums[one],nums[two]
			else:
				one += 1
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值