心路历程
这道题有很多做法,可以用Counter统计数量,也可以排序来做,本来想借此机会复习一下快排,结果给一个小时复习进去了。
快排的双指针还是很厉害的,隐藏了很多的小条件在里面。
注意的点:
1、快排中的双指针防止死循环维持的很巧妙,会用改变当前指针所指的值来防止下一个循环不更新指针
2、RecursionError: maximum recursion意思是递归没有终止,一般都是判断条件错误,这里快排的判断条件需要是end - start <= 0而不能是==0,因为left指针可能在while循环结束后没动,-1之后就会成负数
解法一: 列表快排
class Solution:
def sortColors(self, nums: List[int]) -> None:
"""
Do not return anything, modify nums in-place instead.
"""
# 双指针\ 排序问题 \ 快速排序
# 统计数量的做法可以一次遍历并且O(1)空间复杂度
def quick_sort(anums):
"""空间复杂度高一些的快速排序 O(nlogn)的空间复杂度"""
if not anums:
return []
div = anums[0]
left = quick_sort([l for l in anums[1:] if l <= div])
right = quick_sort([r for r in anums[1:] if r > div])
return left + [div] + right
nums1 = quick_sort(nums)
# nums = [nums1[i] for i in range(len(nums))] # 为何这种赋值方式不行?
for i in range(len(nums)):
nums[i] = nums1[i]
解法二:双指针快排
class Solution:
def sortColors(self, nums: List[int]) -> None:
"""
Do not return anything, modify nums in-place instead.
"""
def dfs(start, end): # 对nums[start: end+1]的元素进行一次分割操作
if end - start <= 0: # RecursionError: maximum recursion depth exceeded 这个报错意思就是递归没到底返回
return
mid = nums[start]
left, right = start, end # left right又写反了
while right > left:
while right > left and nums[right] >= mid:
right -= 1
nums[left] = nums[right]
while right > left and nums[left] < mid:
left += 1
nums[right] = nums[left]
nums[left] = mid
dfs(start, left-1)
dfs(left+1, end)
dfs(0, len(nums)-1)