Open azl397985856 opened 2 years ago
class Solution:
def sortArray(self, nums: List[int]) -> List[int]:
n = len(nums)
def quick_sort(left, right):
if left >= right:
return nums
privot = left
i = left
j = right
while i < j:
while i < j and nums[j] > nums[privot]:
j -= 1
while i < j and nums[i] <= nums[privot]:
i += 1
nums[i], nums[j] = nums[j], nums[i]
nums[privot], nums[j] = nums[j], nums[privot]
quick_sort(left, j - 1)
quick_sort(j + 1, right)
return nums
return quick_sort(0, n - 1)
def sortArray(self, nums):
if len(nums)<=1:
return nums
mid=len(nums)//2
left=self.sortArray(nums[:mid])
right=self.sortArray(nums[mid:])
return self.merge(left,right)
def merge(self,left,right):
i,j=0,0
res=[]
while i<len(left) and j<len(right):
if left[i]<=right[j]:
res.append(left[i])
i+=1
else:
res.append(right[j])
j+=1
res+=left[i:]
res+=right[j:]
return res
排序数组 https://leetcode-cn.com/problems/sort-an-array/comments/
试了很多次,常规的排序算法会超时,所以选用了希尔排序
class Solution {
public:
vector<int> sortArray(vector<int>& nums) {
Shell_Sort(nums);
return nums;
}
void Shell_Sort(vector<int>& nums){
int n = nums.size();
int i,j,gap;
for(gap = n/2;gap>0;gap /=2){
for(i=0;i<gap;i++){
for(j=i+gap;j<n;j+=gap){
if(nums[j] < nums[j-gap]){
int tmp = nums[j];
int k = j-gap;
while(k >= 0 && nums[k] > tmp){
nums[k+gap] = nums[k];
k -= gap;
}
nums[k+gap] = tmp;
}
}
}
}
}
};
时间复杂度:O(nlogn) 空间复杂度:O(1)
快排
var sortArray = function(nums) {
let sort=function (nums, lo, hi) {
if (lo >= hi) {
return;
}
// 对 nums[lo..hi] 进行切分
// 使得 nums[lo..p-1] <= nums[p] < nums[p+1..hi]
let p = partition(nums, lo, hi);
sort(nums, lo, p - 1);
sort(nums, p + 1, hi);
}
// 对 nums[lo..hi] 进行切分
let partition=function (nums, lo, hi) {
let pivot = nums[lo];
// 之后都要正确维护这个边界区间的定义
let i = lo + 1, j = hi;
// 当 i > j 时结束循环,以保证区间 [lo, hi] 都被覆盖
while (i < j) {
while (i < j && nums[i] <= pivot) {
i++;
// 此 while 结束时恰好 nums[i] > pivot
}
while (i < j && nums[j] >= pivot) {
j--;
// 此 while 结束时恰好 nums[j] <= pivot
}
// 此时 [lo, i) <= pivot && (j, hi] >= pivot
swap(nums, i, j);
}
// 将 pivot 放到合适的位置,即 pivot 左边元素较小,右边元素较大
//因为一开始将nums[lo]赋值给了pivot
swap(nums, lo, l);
return l;
}
// 原地交换数组中的两个元素
let swap=function (nums, i, j) {
let temp = nums[i];
nums[i] = nums[j];
nums[j] = temp;
}
// 排序整个数组(原地修改)
sort(nums, 0, nums.length - 1);
return nums;
};
## 复杂度分析
时间O(nlogn)
空间O(logn)
使用的是快排, 轴值需要随机选取 ,不然TLE
class Solution {
public:
vector<int> sortArray(vector<int>& nums) {
quickSort(nums, 0, nums.size() - 1);
return nums;
}
// 以首元素为轴值, 会超时
int partition(vector<int>& nums, int first, int end) {
int i = first;
int j = end;
swap(nums[i], nums[i + rand() % (j - i)]); //随机选取一个作为轴值
while (i < j) {
while (i < j && nums[j] >=nums[i]) {
j--;
}
if (i < j) {
swap(nums[i], nums[j]);
i++;
}
while (i < j && nums[i] <= nums[j]) {
i++;
}
if (i < j) {
swap(nums[i], nums[j]);
j--;
}
}
return i;
}
void quickSort(vector<int>& nums, int first, int end) {
if (first >= end) {
return;
}
int pos = partition(nums, first, end);
quickSort(nums, first, pos - 1);
quickSort(nums, pos + 1, end);
}
};
复杂度分析
class Solution {
//merge sort
public int[] sortArray(int[] nums) {
int[] temp = new int[nums.length];
mergeSort(nums, 0, nums.length-1, temp);
return nums;
}
private void mergeSort(int[] nums, int start, int end, int[] temp){
if(start >= end){
return;
}
int mid = (start + end)/2;
mergeSort(nums, start, mid, temp);
mergeSort(nums, mid+1, end, temp);
merge(nums, start, end, temp);
}
private void merge(int[] nums, int start, int end, int[] temp){
int mid = (start + end)/2;
int left = start, right = mid+1;
int i = left;
while(left <= mid && right <=end){
if(nums[left] <= nums[right]){
temp[i++] = nums[left++];
}else{
temp[i++] = nums[right++];
}
}
while(left <= mid){//now right part is already in temp
temp[i++] = nums[left++];
}
while(right <= end){//now left part is already in temp
temp[i++] = nums[right++];
}
for(int index = start; index<= end; index++){
nums[index] = temp[index];
}
}
}
快排,要随机选指针
class Solution:
def sortArray(self, nums: List[int]) -> List[int]:
self.helper(nums, 0, len(nums) - 1)
return nums
def helper(self, nums, start, end):
if start >= end:
return
pivot = self.partition(nums, start, end)
self.helper(nums, start, pivot - 1)
self.helper(nums, pivot + 1, end)
def partition(self, nums, start, end):
idx = random.randint(start, end)
# idx = end
nums[idx], nums[end] = nums[end], nums[idx]
pivot = nums[end]
wall = start
for i in range(start, end + 1):
if nums[i] < pivot:
nums[wall], nums[i] = nums[i], nums[wall]
wall += 1
nums[end], nums[wall] = nums[wall], nums[end]
return wall
time O(NlogN) space O(logN, 递归树深度)
思路:
归并排序:
代码:
class Solution {
public:
void swap(vector
// 快排
// 归并排序
/*核心思想:
递归,把数组一分为二,然后再合并两个有序列表,使得合并后的数组也是有序的。
*/
MergeSort(nums, 0, nums.size()-1);
return nums;
}
}; 复杂度: onLog(n)
归并排序,计数排序
func sortArray(nums []int) []int {
// return countSort(nums)
return mergeSort(nums)
}
func mergeSort(nums []int) []int {
var merge func(src, help []int, li, mi, hi int)
merge = func(src, help []int, li, mi, hi int) {
for i, p, q := li, li, mi + 1; i <= hi; i++ {
if p > mi {
help[i] = src[q]
q++
} else if q > hi {
help[i] = src[p]
p++
} else {
if src[p] <= src[q] {
help[i] = src[p]
p++
} else {
help[i] = src[q]
q++
}
}
}
for i := li; i <= hi; i++ {
src[i] = help[i]
}
}
var sort func(src, help []int, li, hi int)
sort = func(src, help []int, li, hi int) {
if li == hi { return }
mi := (li + hi) / 2
sort(src, help, li, mi)
sort(src, help, mi + 1, hi)
merge(src, help, li, mi, hi)
}
help := make([]int, len(nums))
sort(nums, help, 0, len(nums) - 1)
return nums
}
func countSort(nums []int) []int {
offset := 50000
cache := make([]int, 100001)
for _, d := range nums {
cache[d + offset]++
}
numsIdx := 0
for idx, count := range cache {
if count == 0 {
continue
}
val := idx - offset
for i := 0; i < count; i++ {
nums[numsIdx] = val
numsIdx++
}
}
return nums
}
复杂度分析
归并排序
计数排序
# 快速排序
import random
class Solution:
def sortArray(self, nums: List[int]) -> List[int]:
def partition(nums, left, right):
flag = random.randint(left, right)
pixov = nums[flag]
nums[left], nums[flag] = nums[flag], nums[left]
while left < right:
while left < right and nums[right] >= pixov:
right -= 1
nums[left] = nums[right]
while left < right and nums[left] <= pixov:
left += 1
nums[right] = nums[left]
nums[left] = pixov
return left
def quickpai(nums, left, right):
#不要忘记下面两句代码,就算return的是空,也得需要return的
if left >= right:
return
mid = partition(nums, left, right)
quickpai(nums, left, mid-1)
quickpai(nums, mid+1, right)
quickpai(nums, 0, len(nums)-1)
return nums
时间复杂度:O(logN) 空间复杂度:O(logN)
归并排序:
vector<int> sortArray(vector<int>& nums)
{
return MergeSort(nums);
}
vector<int> MergeSort(vector<int>& array)
{
if(array.size()<=1)
return array;
int mid=array.size()/2;
vector<int> left;
vector<int> right;
for(int i=0;i<mid;i++)
left.push_back(array[i]);
for(int i=mid;i<array.size();i++)
right.push_back(array[i]);
left.assign(MergeSort(left).begin(),MergeSort(left).end());
right.assign(MergeSort(right).begin(),MergeSort(right).end());
return Merge(left,right);
}
vector<int> Merge(vector<int>& left, vector<int>& right)
{
vector<int> temp;
int pl=0;
int pr=0;
while(pl<left.size() && pr<right.size())
{
if(left[pl]<right[pr])
temp.push_back(left[pl]);
else
temp.push_back(right[pr]);
pl++;
pr++;
}
if(pl<left.size())
{
for(pl;pl<left.size();pl++)
{
temp.push_back(left[pl]);
}
}
if(pr<right.size())
{
for(pr;pr<right.size();pr++)
{
temp.push_back(right[pr]);
}
}
return temp;
}
时间复杂度:O(nlogn) 空间复杂度:O(n)
912. 排序数组
入选理由
暂无
题目地址
https://leetcode-cn.com/problems/sort-an-array/
前置知识
题目描述
示例 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