912. 排序数组
Difficulty: 中等
给你一个整数数组 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
Solution
快速排序实现一:
class Solution:
def sortArray(self, nums: List[int]) -> List[int]:
left, right = 0, len(nums)-1
self.qSort(nums, left, right)
return nums
def qSort(self, arr, low, high):
if len(arr) <= 1:
return arr
if low < high:
pivot = self.partition(arr, low, high)
self.qSort(arr, low, pivot-1)
self.qSort(arr, pivot+1, high)
def partition(self, arr, low, high):
i = low - 1
pivot = arr[high]
for j in range(low, high):
if arr[j] <= pivot:
i += 1
arr[i], arr[j] = arr[j], arr[i]
arr[i+1], arr[high] = arr[high], arr[i+1]
return i+1
现在这题如果写快速排序必须得选随机基准值才能过,不然会超时,补充一个随机选择基准值的解法:
import random
class Solution:
def sortArray(self, nums: List[int]) -> List[int]:
left, right = 0, len(nums) - 1
self.qsort(nums, left, right)
return nums
def qsort(self, arr, low, high):
if len(arr) <= 1:
return arr
if low < high:
p = self.partition(arr, low, high)
self.qsort(arr, low, p-1)
self.qsort(arr, p+1, high)
def partition(self, arr, low, high):
i = low - 1
p = random.randint(low, high)
arr[p], arr[high] = arr[high], arr[p]
pivot = arr[high]
for j in range(low, high):
if arr[j] <= pivot:
i += 1
arr[i], arr[j] = arr[j], arr[i]
arr[i+1], arr[high] = arr[high], arr[i+1]
return i+1
快速排序实现二:
class Solution:
def sortArray(self, nums: List[int]) -> List[int]:
# 快速排序
less = []
more = []
pivot_list = []
if len(nums) <= 1:
return nums
else:
pivot = nums[0]
for item in nums:
if item < pivot:
less.append(item)
elif item > pivot:
more.append(item)
else:
pivot_list.append(item)
less = self.sortArray(less)
more = self.sortArray(more)
return less + pivot_list + more
冒泡排序,不过超出了时间限制,没有通过。
class Solution:
def sortArray(self, nums: List[int]) -> List[int]:
if not nums:
return []
num_len = len(nums)
for i in range(num_len-1,0,-1):
for j in range(i):
if nums[j] > nums[j+1]:
nums[j], nums[j+1] = nums[j+1], nums[j]
return nums
插入排序,同样也超出了时间限制,没有通过。
class Solution:
def sortArray(self, nums: List[int]) -> List[int]:
if not nums:
return []
num_len = len(nums)
for i in range(1, num_len):
key = nums[i]
j = i - 1
while j >= 0 and key < nums[j]:
nums[j+1] = nums[j]
j -= 1
nums[j+1] = key
return nums
堆排序
- 最后一个非叶子节点
(n // 2 - 1)
开始构建大顶堆或小顶堆,在构建堆的过程中原有的顺序可能会被破坏,这时需要重新构建大顶堆或小顶堆 - 将堆顶元素与数组的末尾元素交换,然后重复上一个步骤
class Solution:
def sortArray(self, nums: List[int]) -> List[int]:
self.heapSort(nums)
return nums
def heapify(self, arr, n, i):
largest = i
l = 2 * i + 1 # 左子节点
r = 2 * i + 2 # 右子节点
if l < n and arr[largest] < arr[l]:
largest = l
if r < n and arr[largest] < arr[r]:
largest = r
if largest != i:
arr[largest], arr[i] = arr[i], arr[largest]
self.heapify(arr, n, largest) # 在处理新的叶子节点后会导致原来排序好的堆混乱了,所以需要重新进行堆排序
# 堆排序
def heapSort(self, arr):
n = len(arr)
# 从最后一个非叶子节点开始构建最大堆
for i in range(n // 2 - 1, -1, -1):
self.heapify(arr, n, i)
for i in range(n-1, 0, -1):
arr[i], arr[0] = arr[0], arr[i] # 堆顶的最大元素交换到堆底
self.heapify(arr, i, 0)