vlambda博客
学习文章列表

39.[中等]排序数组--快速排序

题目

给你一个整数数组 nums,请你将该数组升序排列。

示例 1
输入:nums = [5,2,3,1]
输出:[1,2,3,5]


示例 2
输入:nums = [5,1,1,2,0,0]
输出:[0,0,1,1,2,5]

提示:
1 <= nums.length <= 50000
-50000 <= nums[i] <= 50000

快速排序

快速排序我的理解上也是将数组分为小数组进行排序。和归并排序不同, 归并排序更类似于以索引进行划分, 从中间将数组一分为二, 不断划分后再合并。而快速排序则是以数组中某一个数为基准, 将数组分为大于等于这个数和小于这个数两堆(或者小于等于和大于也可以),从两堆数组里再分别取一个基准, 再次进行划分, 不断重复上面的过程, 直到数组元素个数为 1 停止。这时整个数组就保持了一个有序的状态。

上面是一个快速排序的一个大概思路, 里面最关键的就是如何将数组以基准值为边界, 划分为两堆数组。

我看到的一个思路是挖坑法, 最开始以左右边界设定两个索引, 基准值取左边界为基准, 此时使用记下当前基准所在索引记为坑位, 这时候从右边界开始找小于基准值的数, 找到这个值(假设为j)后将这个值赋值到坑位中, 此时将坑位更新为j。

然后再从左边开始寻找大于基准的值, 找到后(假设为i)将这个值赋值到坑位中, 此时将坑位更新为i。

不断重复上述步骤, 知道左右索引重合, 将基准值赋值到做索引中。就完成了一轮划分排序。

快速排序
def quickSort(nums, left, right):
if left >= right:
return nums

# 左右指针
left_index = left
right_index = right

# 基准值
temp = nums[left]

pre_index = left_index

while left_index < right_index:
if pre_index == left_index and temp > nums[right_index]:
nums[pre_index] = nums[right_index]
pre_index = right_index
left_index += 1
elif pre_index == left_index and temp <= nums[right_index]:
right_index -= 1
elif pre_index == right_index and temp > nums[left_index]:
left_index += 1
elif pre_index == right_index and temp <= nums[left_index]:
nums[pre_index] = nums[left_index]
pre_index = left_index
right_index -= 1

nums[left_index] = temp

quickSort(nums, left, left_index)
quickSort(nums, left_index+1, right)

return nums


class Solution:
def sortArray(self, nums: List[int]) -> List[int]:
return quickSort(nums, 0, len(nums) - 1)