Open azl397985856 opened 2 years ago
class Solution:
def sortArray(self, nums: List[int]) -> List[int]:
"""
Ideas: Count Sort
build a large list to save occurence of num
then enumerate it to get result
TC: O(n)
SC: O(100001)
"""
count = [0 for i in range(50000 * 2 + 1)]
for num in nums:
count[num + 50000] += 1
res = []
for i in range(len(count)):
num = i
occurence = count[i]
for j in range(occurence):
res.append(num - 50000)
return res
def sortArray(self, nums: List[int]) -> List[int]:
"""
Ideas:quick sort
https://leetcode-cn.com/problems/sort-an-array/solution/duo-chong-pai-xu-yi-wang-da-jin-kuai-pai-wgz4/
TC: O(nlogn)
TC: O(n*1)
"""
def partition(arr, low, high):
pivot_idx = random.randint(low, high) # 随机选择pivot
arr[low], arr[pivot_idx] = arr[pivot_idx], arr[low] # pivot放置到最左边
pivot = arr[low] # 选取最左边为pivot
left, right = low, high # 双指针
while left < right:
while left<right and arr[right] >= pivot: # 找到右边第一个<pivot的元素
right -= 1
arr[left] = arr[right] # 并将其移动到left处
while left<right and arr[left] <= pivot: # 找到左边第一个>pivot的元素
left += 1
arr[right] = arr[left] # 并将其移动到right处
arr[left] = pivot # pivot放置到中间left=right处
return left
def quickSort(arr, low, high):
if low >= high: # 递归结束
return
mid = partition(arr, low, high) # 以mid为分割点,右边元素>左边元素
quickSort(arr, low, mid-1) # 递归对mid两侧元素进行排序
quickSort(arr, mid+1, high)
quickSort(nums, 0, len(nums)-1) # 调用快排函数对nums进行排序
return nums
class Solution {
public:
vector
for(int i = 50001; i > 0; i--) {
if (numsCount[i] > 0) {
for(int j = 0; j < numsCount[i]; j++) {
ret.push_back(-i);
}
numsCount[i] = 0;
}
}
cout<<numsCount[2]<<endl;
for(auto i : nums) {
if (i >= 0) {
numsCount[i]++;
}
}
for(int i = 0; i < 50002; i++) {
if (numsCount[i] > 0) {
for(int j = 0; j < numsCount[i]; j++) {
ret.push_back(i);
}
}
}
return ret;
} };
class Solution:
def sortArray(self, nums: List[int]) -> List[int]:
count_arr = [0] * (50000*2 + 1)
res = []
for num in nums:
count_arr[num+50000] += 1
for i in range(len(count_arr)):
if count_arr[i] > 0:
for _ in range(count_arr[i]):
res.append(i-50000)
return res
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];
}
}
}
Count Sort
class Solution:
def sortArray(self, nums: List[int]) -> List[int]:
count = collections.Counter(nums)
ans=[]
for i in range(-5 * 10**4, 5 * 10**4+1):
if i in count:
ans+=[i]*count[i]
return ans
Time: O(5 * 10**4) Space: O(M). M: the count of unique numbers in array
https://leetcode-cn.com/problems/sort-an-array/
给你一个整数数组 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 <= 5 * 104
-5 * 104 <= nums[i] <= 5 * 104
Java Code:
class Solution {
public int[] sortArray(int[] nums) {
if(nums==null||nums.length<2){
return nums;
}
quickSort(nums,0,nums.length-1);
return nums;
}
private void quickSort(int[] nums,int start,int end){
if(nums.length<1||start<0||end>nums.length||start>end){
return;
}
if(start<end){
int left = start;
int right = end;
int pivot = nums[start];
while(left<right){
//从右边开始,如果循环结束且left<right,表示右边小于基准值
while(left<right&&nums[right]>=pivot){
right--;
}
//右移左指针
if(left<right){
nums[left++]=nums[right];
}
//从左边继续移动
while(left<right&&nums[left]<=pivot){
left++;
}
//把大于基准值扔到右边去
if(left<right){
nums[right--]=nums[left];
}
}
if(left==right){
nums[left]=pivot;
}
quickSort(nums,start,left-1);
quickSort(nums,left+1,end);
}
}
}
复杂度分析
令 n 为数组长度。
Quick sort
class Solution {
public int[] sortArray(int[] nums) {
quick(nums, 0, nums.length - 1);
return nums;
}
public void quick(int[] nums, int left, int right) {
if (left >= right) return;
int pivot = partition(nums, left, right);
quick(nums, left, pivot - 1);
quick(nums, pivot + 1, right);
}
public int partition(int[] nums, int left, int right) {
int p = (right - left) / 2 + left;
swap(nums, p, right);
int i = left, j = left;
while (j < right) {
if(nums[j] <= nums[right]) {
swap(nums, i, j);
i++;
}
j++;
}
swap(nums, i, right);
return i;
}
public void swap(int[] nums, int i, int j) {
int tmp = nums[i];
nums[i] = nums[j];
nums[j] = tmp;
}
}
time=O(nlogn) space=O(logn)
快排
var sortArray = function(nums) {
const n = nums.length;
if (n <= 1) {
return nums;
}
const mid = Math.floor(n / 2);
let pivot = nums.splice(mid, 1)[0];
let lArr = [], rArr = [];
for (let i = 0; i < n - 1; i++) {
if (nums[i] > pivot) {
rArr.push(nums[i]);
} else {
lArr.push(nums[i]);
}
}
return sortArray(lArr).concat([pivot], sortArray(rArr));
}
Day36
1、采用快速排序的方式
2、选择数组中的中间位置作为枢
3、枢左侧放入left,右侧放入right
4、left和right再递归调用
5、返回left+枢+right
var sortArray = function(nums) {
if(nums.length<2) return nums
const pivotIndex=Math.floor(nums.length/2)
const pivot=nums.splice(pivotIndex,1)[0]
//该语句是既取出中间元素又删掉原数组的中间元素
//splice返回一个长度为1数组,取该数组的首位
let left=[]
let right=[]
for(let n of nums){
if(n<pivot){
left.push(n)
}
else{
right.push(n)
}
}
return sortArray(left).concat(pivot,sortArray(right))
};
时间复杂度:O(nlogn)
空间复杂度:O(logn)
计数排序
def sortArray(self, nums: List[int]) -> List[int]:
count_temp = collections.Counter(nums)
res = []
for i in range(-5 * 10**4, 5 * 10**4 + 1):
if i in count_temp:
res += [i] * count_temp[i]
return res
时间 O(10**5) \ 空间 O(n)
使用快速排序
Python3 Code:
class Solution:
def sortArray(self, nums: List[int]) -> List[int]:
"""
升序数组
"""
# 使用快排
self.QuickSort(nums,0,len(nums)-1)
return nums
def QuickSort(self,nums,l,r):
if l >= r:
return
i = self.partition(nums,l,r)
self.QuickSort(nums,l,i-1)
self.QuickSort(nums,i+1,r)
def partition(self,nums,l,r):
# 最好不要选择第一个元素 否则遇到顺序的数组 时间复杂度退化到O(n^2)
pivot_idx = random.randint(l,r)
nums[l],nums[pivot_idx] = nums[pivot_idx],nums[l]
pivot = nums[l]
i,j = l,r
while i < j:
# 移动右指针
while i < j and nums[j] >= pivot:
j -= 1
nums[i] = nums[j]
# 移动左指针
while i < j and nums[i] <= pivot:
i += 1
nums[j] = nums[i]
nums[i] = pivot
return i
归并排序
class Solution(object):
def sortArray(self, nums):
"""
:type nums: List[int]
:rtype: List[int]
"""
self.merge_sort(nums, 0, len(nums)-1)
return nums
def merge_sort(self, arr, L, R):
if L == R:
return
mid = L + (R-L)//2
self.merge_sort(arr, L, mid)
self.merge_sort(arr, mid+1, R)
self.merge(arr, L, mid, R)
def merge(self, arr, L, mid, R):
tmp = []
p1, p2 = L, mid+1
while p1 <= mid and p2 <= R:
if arr[p1] <= arr[p2]:
tmp.append(arr[p1])
p1 += 1
else:
tmp.append(arr[p2])
p2 += 1
while p1 <= mid:
tmp.append(arr[p1])
p1 += 1
while p2 <= R:
tmp.append(arr[p2])
p2 += 1
arr[L:R+1] = tmp
时间复杂度Onlogn 空间复杂度On
手写归并排序
class Solution {
public int[] sortArray(int[] nums) {
int[] tmp = new int[nums.length];
sort(nums, 0, nums.length - 1, tmp);
return nums;
}
private void sort(int[] nums, int a, int b, int[] tmp) {
if (a == b)
return;
int mid = a + (b - a) / 2;
sort(nums, a, mid, tmp);
sort(nums, mid + 1, b, tmp);
int l = a;
int r = mid + 1;
int index = a;
while (l <= mid && r <= b) {
if (nums[l] < nums[r]) {
tmp[index++] = nums[l++];
} else {
tmp[index++] = nums[r++];
}
}
while (l <= mid) {
tmp[index++] = nums[l++];
}
while (r <= b) {
tmp[index++] = nums[r++];
}
for (int i = a; i <= b; i++) {
nums[i] = tmp[i];
}
}
}
给你一个整数数组 nums,请你将该数组升序排列。
示例 1
输入:nums = [5,2,3,1] 输出:[1,2,3,5]
前置知识
快速排序,通过每次选取pivot点,小于pivot放左边,大于pivot放右边,递归下去,最后左右合并,通过拆分和合并的方式实现有序
var sortArray = function(nums) {
const arr = [...nums];
if(arr.length < 2) return arr;
const pivotIndex = Math.floor(arr.length / 2);
const pivot = arr[pivotIndex];
const [lo,hi] = arr.reduce(
(acc, val, i) => {
if(val < pivot || (val === pivot && i != pivotIndex)){
acc[0].push(val)
}else if (val > pivot){
acc[1].push(val)
}
return acc;
}
,[[],[]])
return [...sortArray(lo),pivot,...sortArray(hi)];
};
时间复杂度:O(nlogn) 空间复杂度:O(n)
使用堆进行排序
class Solution {
public:
vector<int> sortArray(vector<int>& nums) {
int n = nums.size();
priority_queue<int,vector<int>,greater<int>> q;
for(int i = 0; i< n; i++)
{
q.push(nums[i]);
}
for(int i = 0; i<n;i++)
{
nums[i] = q.top();
q.pop();
}
return nums;
}
};
Merge Sort
class Solution {
public int[] sortArray(int[] nums) {
mergeSort(nums, 0, nums.length-1);
return nums;
}
public void mergeSort (int[] nums, int l, int r) {
// ❗️这里一定要是 if 而不是 while 要不然 infinite loop!
if (l < r) {
int m = l + (r - l) / 2;
mergeSort(nums, l, m);
mergeSort(nums, m+1, r);
merge(nums, l, m, r);
}
}
public void merge (int[] nums, int l, int m, int r) {
// Divide nums into two parts
int n1 = m - l + 1;
int n2 = r - m;
int[] arr1 = new int[n1];
int[] arr2 = new int[n2];
for (int i=0; i<n1; i++) {
arr1[i] = nums[i + l];
}
for (int i=0; i<n2; i++) {
arr2[i] = nums[i + m + 1];
}
// Merge two array
int ls = 0, rs = 0, index = l;
while (ls < n1 && rs < n2) {
if (arr1[ls] <= arr2[rs]) {
nums[index] = arr1[ls];
ls++;
} else {
nums[index] = arr2[rs];
rs++;
}
index++;
}
while (ls < n1) {
nums[index] = arr1[ls];
index++;
ls++;
}
while (rs < n2) {
nums[index] = arr2[rs];
index++;
rs++;
}
}
}
class Solution:
def sortArray(self, nums: List[int]) -> List[int]:
self.mergeSort(nums)
return nums
def mergeSort(self, nums):
if len(nums) > 1:
mid = len(nums)//2
L = nums[:mid]
R = nums[mid:]
self.mergeSort(L)
self.mergeSort(R)
i = j = k = 0
while i < len(L) and j < len(R):
if L[i] < R[j]:
nums[k] = L[i]
i+=1
else:
nums[k] = R[j]
j+=1
k+=1
while i < len(L):
nums[k] = L[i]
i+=1
k+=1
while j < len(R):
nums[k] = R[j]
j+=1
k+=1
Time: O(nlogn) Space: O(n)
merge sort.
class Solution:
def sortArray(self, nums: List[int]) -> List[int]:
if len(nums) <= 1: return nums
mid = len(nums)//2
left = self.sortArray(nums[:mid])
right = self.sortArray(nums[mid:])
return self.mergeSort(left, right)
def mergeSort(self,left, right):
res = []
i, j = 0, 0
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
time complexity: O(N longN) space complexity: O(N)
"""
class Solution:
def sortArray(self, nums: List[int]) -> List[int]:
l = len(nums)
if l <= 1:
return nums
arr1 = self.sortArray(nums[:l//2])
arr2 = self.sortArray(nums[l//2:])
res = self.mergeSortedArray(arr1, arr2)
return res
def mergeSortedArray(self, arr1, arr2):
res = []
p1, p2 = 0, 0
while p1 < len(arr1) and p2 < len(arr2):
if arr1[p1] <= arr2[p2]:
res.append(arr1[p1])
p1 += 1
else:
res.append(arr2[p2])
p2 += 1
if p1 < len(arr1):
res += arr1[p1:]
if p2 < len(arr2):
res += arr2[p2:]
return res
"""
class Solution:
def sortArray(self, nums: List[int]) -> List[int]:
self.quickSort(nums, 0, len(nums)-1)
return nums
def quickSort(self, nums, l, r):
if l >= r:
return
p = self.partition(nums, l, r)
self.quickSort(nums, l, p-1)
self.quickSort(nums, p+1, r)
def partition(self, nums, l, r):
mid = l + (r-l)//2
pivot = nums[mid]
nums[l], nums[mid] = nums[mid], nums[l]
i = l+1
j = r
while i <= j:
while i <= j and nums[i] <= pivot:
i += 1
while i <= j and nums[j] >= pivot:
j -= 1
if i < j:
nums[i], nums[j] = nums[j], nums[i]
nums[l], nums[j] = nums[j], nums[l]
return j
class Solution:
def sortArray(self, nums: List[int]) -> List[int]:
nums.sort()
return nums
class Solution {
public int[] sortArray(int[] nums) {
Arrays.sort(nums);
return nums;
}
}
class Solution { public int[] sortArray(int[] nums) {
if (nums.length == 0) { return nums;}
QuickSort(nums, 0, nums.length - 1);
return nums;
}
private void QuickSort(int[] nums, int start, int end) {
if(start >= end) return;
int pivot = nums[(start + end)/2];
int left = start, right = end;
while (left <= right) {
while (left <= right && nums[left] < pivot ) {
left++;
}
while (left <= right && nums[right] > pivot) {
right--;
}
if(left <= right) {
int temp;
temp = nums[left];
nums[left] = nums[right];
nums[right] = temp;
left++;
right--;
}
}
QuickSort(nums, start, right);
QuickSort(nums, left, end);
}
}
class Solution:
def quickSort(self, nums):
def helper(head, tail):
if head >= tail: return
l, r = head, tail
m = (r - l) // 2 + l
pivot = nums[m]
while r >= l:
while r >= l and nums[l] < pivot: l += 1
while r >= l and nums[r] > pivot: r -= 1
if r >= l:
nums[l], nums[r] = nums[r], nums[l]
l += 1
r -= 1
helper(head, r)
helper(l, tail)
helper(0, len(nums)-1)
return nums
def sortArray(self, nums: List[int]) -> List[int]:
self.quickSort(nums)
return nums
讲义里的冒泡排序
class Solution {
public int[] sortArray(int[] nums) {
for(int i = 0; i<nums.length-1;i++){
for(int j = 1; j<nums.length - i ;j++){
if(nums[j-1] > nums[j]){
int temp = nums[j-1];
nums[j-1] = nums[j];
nums[j] = temp;
}
}
}
return nums;
}
}
class Solution {
public int[] sortArray(int[] nums) {
// selectionSort(nums);
// insertionSort(nums, 0, nums.length - 1);
// shellSort(nums);
quickSort(nums, 0, nums.length - 1);// 最快
// mergeSort(nums, 0, nums.length - 1, new int[nums.length]);
// radixSort(nums); // 报错,因为基数排序不支持排序负数
//heapSort(nums);
return nums;
}
// 冒泡排序 O(n^2):可通过判断一轮比较后没有进行交换提前跳出来优化
void bubbleSort(int[] nums) {
// 比较次数
for (int i = 0; i < nums.length - 1; i++) {
// 每次比较需要遍历的下标
for (int j = 0; j < nums.length - 1 - i; j++) {
if (nums[j] > nums[j + 1]) {
swap(nums, j, j + 1);
}
}
}
}
// 选择排序 O(n^2)
void selectionSort(int[] nums) {
for (int i = 0; i < nums.length - 1; i++) {
int minIndex = i;
int min = nums[i];
for (int j = i + 1; j < nums.length; j++) {
if (nums[j] < min) {
min = nums[j];
minIndex = j;
}
}
swap(nums, i, minIndex);
}
}
// 插入排序 O(n^2)
void insertionSort(int[] nums, int left, int right) {
for (int i = left + 1; i <= right; i++) {
int insertedVal = nums[i];
int insertedIndex = i - 1;// 待插入数前面数的下标
while (insertedIndex >= 0 && insertedVal < nums[insertedIndex]) {
nums[insertedIndex + 1] = nums[insertedIndex];
insertedIndex--;
}
nums[insertedIndex + 1] = insertedVal;
}
}
// 希尔排序 O(nlog^2(n)):增量分组 + 插入排序
void shellSort(int[] nums) {
for (int gap = nums.length / 2; gap > 0; gap /= 2) {
for (int i = gap; i < nums.length; i++) {
int insertedVal = nums[i];
int insertedIndex = i - gap;
while (insertedIndex >= 0 && insertedVal < nums[insertedIndex]) {
nums[insertedIndex + gap] = nums[insertedIndex];
insertedIndex -= gap;
}
nums[insertedIndex + gap] = insertedVal;
}
}
}
// 快速排序 O(nlog(n)):冒泡排序的改进
final int INSERTION_SORT_THRESHOLD = 7;
void quickSort(int[] nums, int left, int right) {
// 小于一定阈值换用插入排序
if (right - left <= INSERTION_SORT_THRESHOLD) {
insertionSort(nums, left, right);
return;
}
int pIndex = partition(nums, left, right);
quickSort(nums, left, pIndex - 1);
quickSort(nums, pIndex + 1, right);
}
Random random = new Random();
int partition(int[] nums, int left, int right) {
int randomIndex = left + random.nextInt(right - left + 1);
swap(nums, left, randomIndex);
int pivot = nums[left];
int lt = left;
for (int i = left + 1; i <= right; i++) {
if (nums[i] < pivot) {
lt++;
swap(nums, i, lt);
}
}
swap(nums, lt, left);
return lt;
}
// 归并排序 O(nlog(n))
void mergeSort(int[] nums, int left, int right, int[] tmp) {
if (left >= right) {
return;
}
int mid = left + (right - left) / 2;
mergeSort(nums, left, mid, tmp);
mergeSort(nums, mid + 1, right, tmp);
merge(nums, left, right, tmp);
}
void merge(int[] nums, int left, int right, int[] tmp) {
// 1. 合并到临时数组
int mid = left + (right - left) / 2;
int i = left, j = mid + 1, t = 0;
while (i <= mid && j <= right) {
if (nums[i] <= nums[j]) {
tmp[t++] = nums[i++];
} else {
tmp[t++] = nums[j++];
}
}
while (i <= mid) {
tmp[t++] = nums[i++];
}
while (j <= right) {
tmp[t++] = nums[j++];
}
// 2. 复制回原数组
t = 0;
i = left;
while (i <= right) {
nums[i++] = tmp[t++];
}
}
// 基数排序 O(n * bucketSum):空间换时间的经典算法,不支持排序负数
void radixSort(int[] nums) {
final int RADIX = 10;
int[][] bucket = new int[RADIX][nums.length];
int[] bucketElementCount = new int[RADIX];
int max = nums[0];
for (int i = 0; i < nums.length; i++) {
max = Math.max(max, nums[i]);
}
int maxDigit = ("" + max).length();
for (int i = 0, digit = 1; i < maxDigit; i++, digit *= 10) {
for (int j = 0; j < nums.length; j++) {
int digitElement = nums[j] / digit % 10;
bucket[digitElement][bucketElementCount[digitElement]] = nums[j];
bucketElementCount[digitElement]++;
}
int index = 0;
for (int k = 0; k < RADIX; k++) {
for (int l = 0; l < bucketElementCount[k]; l++) {
nums[index++] = bucket[k][l];
}
bucketElementCount[k] = 0;
}
}
}
// 堆排序 O(nlog(n))
void heapSort(int[] nums) {
for (int i = nums.length / 2 - 1; i >= 0; i--) {
adjustHeap(nums, nums.length, i);
}
for (int i = nums.length - 1; i >= 0; i--) {
swap(nums, i, 0);
adjustHeap(nums, i, 0);
}
}
void adjustHeap(int[] nums, int len, int nodeIndex) {
int tmp = nums[nodeIndex];
for (int i = 2 * nodeIndex + 1; i < len; i = 2 * i + 1) {
if (i + 1 < len && nums[i + 1] > nums[i]) {
i++;
}
if (nums[i] > tmp) {
nums[nodeIndex] = nums[i];
nodeIndex = i;
} else {
break;
}
}
nums[nodeIndex] = tmp;
}
void swap(int[] nums, int a, int b) {
int tmp = nums[a];
nums[a] = nums[b];
nums[b] = tmp;
}
}
归并排序
impl Solution {
pub fn sort_array(nums: Vec<i32>) -> Vec<i32> {
Self::merge_sort(&nums)
}
fn merge_sort(src: &[i32]) -> Vec<i32> {
if src.len() <= 1 {
return src.to_vec();
}
let mid = src.len() / 2;
let pt1 = Self::merge_sort(&src[..mid]);
let pt2 = Self::merge_sort(&src[mid..src.len()]);
let mut res = vec![];
let mut i = 0;
let mut j = 0;
while i < pt1.len() || j < pt2.len() {
if i < pt1.len() && j < pt2.len() {
if pt1[i] < pt2[j] {
res.push(pt1[i]);
i += 1;
} else {
res.push(pt2[j]);
j += 1;
}
} else if i < pt1.len() {
res.push(pt1[i]);
i += 1;
} else if j < pt2.len() {
res.push(pt2[j]);
j += 1;
}
}
res
}
}
本题思路采用归并排序算法,此题需掌握,快速排序,归并排序,堆排序
class Solution {
//具体实现细节
void merge(vector<int>& nums,int left,int right,vector<int>& ans)
{
int mid=(right-left)/2+left;
int i=left,j=mid+1,k=0;
//情况1
while(i<=mid&&j<=right)
{
//注意写成 < 就丢失了稳定性(相同元素原来靠前的排序以后依然靠前)
if(nums[i]<=nums[j]){
//可以写成ans[k++]=nums[i++]
ans[k]=nums[i];
i++;
k++;
}
else {
ans[k]=nums[j];
j++;
k++;
}
}
//情况2
while(i<=mid)
{
ans[k]=nums[i];
i++;
k++;
}
//情况3
while(j<=right){
ans[k]=nums[j];
j++;
k++;
}
//将临时数组tmp的数组复制到nums中,为什么是i-left?????
for(int i=left;i<=right;i++)
nums[i]=ans[i-left];
}
//递归
void mergeSort(vector<int>& nums,int left,int right,vector<int>& ans)
{
//递归结束标志
if(left>=right)
return ;
//设置中间值,这样写是为了保证数据过大时不溢出
int mid=(right-left)/2+left;
//递归地将数组分为一个个有序序列
mergeSort(nums,left,mid,ans);
mergeSort(nums,mid+1,right,ans);
//再次调用递归将两部分有序数组合二为一
merge(nums,left,right,ans);
}
public:
vector<int> sortArray(vector<int>& nums) {
vector <int> ans(nums.size());
mergeSort(nums,0,nums.size()-1,ans);
return nums;
}
};
快速排序 import random class Solution(object): def randomized_partition(self, nums, l, r): pivot = random.randint(l, r) nums[pivot], nums[r] = nums[r], nums[pivot] i = l - 1 for j in range(l, r): if nums[j] < nums[r]: i += 1 nums[i], nums[j] = nums[j], nums[i] i += 1 nums[i], nums[r] = nums[r], nums[i] return i
def randomized_quicksort(self, nums, l, r):
if r - l <= 0:
return
mid = self.randomized_partition(nums, l, r)
self.randomized_quicksort(nums, l, mid - 1)
self.randomized_quicksort(nums, mid + 1, r)
def sortArray(self, nums):
self.randomized_quicksort(nums, 0, len(nums) - 1)
return nums
https://leetcode-cn.com/problems/sort-an-array/
解法一:快速排序
解法二:计数排序(不写)
解法一:
<?php
class Solution {
/**
* @param Integer[] $nums
* @return Integer[]
*/
function sortArray($nums) {
if (count($nums) < 2) {
return $nums;
}
$middle = $nums[0];
$leftArray = [];
$rightArray = [];
for ($i = 1; $i < count($nums); $i++) {
if ($middle > $nums[$i]) {
$leftArray[] = $nums[$i];
} else {
$rightArray[] = $nums[$i];
}
}
$leftArray = $this->sortArray($leftArray);
$leftArray[] = $middle;
$rightArray = $this->sortArray($rightArray);
return array_merge($leftArray, $rightArray);
}
}
func sortArray(nums []int) []int {
return _quickSort(nums, 0, len(nums) -1)
}
func _quickSort(arr []int, left, right int) []int{
if left < right {
index := partition(arr, left, right)
_quickSort(arr, left, index-1)
_quickSort(arr, index+1, right)
}
return arr
}
func partition(arr []int, left, right int) int {
pivot := left;
index := pivot+1
for i := index; i <= right; i++ {
if arr[pivot] > arr[i] {
swap(arr, i, index)
index += 1
}
}
swap(arr, pivot, index -1)
return index -1
}
func swap(arr []int, i, j int) {
arr[i], arr[j] = arr[j], arr[i]
}
时间复杂度:O(nlogn) 空间复杂度:O(logn)
class Solution {
public:
vector<int> sortArray(vector<int>& nums) {
sort(nums.begin(), nums.end());
return nums;
}
};
/**
* @param {number[]} nums
* @return {number[]}
*/
var sortArray = function(nums) {
if( nums.length <= 1 ) return nums
let left = []
let right = []
let pivotIndex = Math.floor(nums.length / 2)
let pivotValue = nums.splice(pivotIndex,1)[0]
for(let i = 0; i < nums.length; i++ ){
if(nums[i] > pivotValue){
right.push(nums[i])
}else{
left.push(nums[i])
}
}
return sortArray(left).concat(pivotValue,sortArray(right))
};
我只会调用,是个傻逼
class Solution:
def sortArray(self, nums: List[int]) -> List[int]:
nums.sort()
return nums
归并排序
var sortArray = function(nums) {
if (nums.length === 1) return nums;
return mergeSort(nums, 0, nums.length - 1);
};
const mergeSort = function(nums, start, end) {
if (start >= end) return [nums[start]];
let mid = start + ((end - start) >> 1);
let left = mergeSort(nums, start, mid);
let right = mergeSort(nums, mid + 1, end);
return sortOrderlyArray(left, right);
};
const sortOrderlyArray = function(a, b) {
let i = 0, j = 0;
let res = [];
while (i < a.length || j < b.length) {
if (i >= a.length || a[i] > b[j]) {
res.push(b[j]);
j++;
continue;
}
if (j >= b.length || a[i] <= b[j]) {
res.push(a[i]);
i++;
}
}
return res;
};
time: O(nlogn)
space: O(n)
归并
class Solution {
public:
vector<int> tmp;
void mergesort(vector<int>& nums,int l,int r){
if(l>=r) return;
int mid=(l+r)>>1;
mergesort(nums,l,mid);
mergesort(nums,mid+1,r);
int i=l,j=mid+1;
int cnt=0;
while(i<=mid&&j<=r){
if(nums[i]<=nums[j]) tmp[cnt++]=nums[i++];
else tmp[cnt++]=nums[j++];
}
while(i<=mid){
tmp[cnt++]=nums[i++];
}
while(j<=r){
tmp[cnt++]=nums[j++];
}
for(int i=0;i<r-l+1;i++){
nums[i+l]=tmp[i];
}
}
vector<int> sortArray(vector<int>& nums) {
tmp.resize((int)nums.size(),0);
mergesort(nums,0,(int)nums.size()-1);
return nums;
}
};
快排
class Solution:
def sortArray(self, nums: List[int]) -> List[int]:
def quicksort(nums,left,right):
flag=nums[(left+right)//2]
i,j=left,right
while i<=j:
while nums[i]<flag: i+=1
while nums[j]>flag: j-=1
if i<=j:
nums[i],nums[j]=nums[j],nums[i]
i+=1
j-=1
if i<right: quicksort(nums,i,right)
if j>left: quicksort(nums,left,j)
quicksort(nums,0,len(nums)-1)
return nums
class Solution:
def sortArray(self, nums: List[int]) -> List[int]:
def partition(arr,low,high):
pivot_idx=random.randint(low,high) # 随机选择pivot
arr[low],arr[pivot_idx]=arr[pivot_idx],arr[low] # pivot放置到最左边
pivot=arr[low]
left,right=low,high
while left<right:
while left<right and arr[right]>=pivot: # 找到右边第一个<pivot的元素
right-=1
arr[left]=arr[right]
while left<right and arr[left]<=pivot:
# 找到左边第一个>pivot的元素
left+=1
arr[right]=arr[left]
arr[left]=pivot # pivot放置到中间left=right处
return left
def quickSort(arr,low,high):
if low>high:
return
mid=partition(arr,low,high) # 以mid为分割点,右边元素>左边元素
quickSort(arr,low,mid-1)
quickSort(arr,mid+1,high)
quickSort(nums,0,len(nums)-1)
return nums
时间复杂度:O(nlogn)
空间复杂度:O(logn)
https://leetcode-cn.com/problems/sort-an-array/
给你一个整数数组 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 <= 5 * 104
-5 * 104 <= nums[i] <= 5 * 104
冒泡排序超时
快速排序
语言支持:JavaScript
JavaScript Code:
/**
* @param {number[]} nums
* @return {number[]}
*/
var sortArray = function(nums) {
if (nums.length <= 1) { return nums; }
var pivotIndex = Math.floor(nums.length / 2);
var pivot = nums.splice(pivotIndex, 1)[0];
var left = [];
var right = [];
for (var i = 0; i < nums.length; i++){
if (nums[i] < pivot) {
left.push(nums[i]);
} else {
right.push(nums[i]);
}
}
return sortArray(left).concat([pivot], sortArray(right));
};
复杂度分析
令 n 为数组长度。
快速排序
class Solution:
def sortArray(self, nums: List[int]) -> List[int]:
self.quickSort(nums, 0, len(nums)-1)
return nums
def partition(self, arr, low, high):
pivot_idx = random.randint(low, high)
arr[low], arr[pivot_idx] = arr[pivot_idx], arr[low]
pivot = arr[low]
left, right = low, high
while left < right:
while left < right and arr[right] >= pivot:
right -= 1
arr[left] = arr[right]
while left < right and arr[left] <= pivot:
left += 1
arr[right] = arr[left]
arr[left] = pivot
return left
def quickSort(self, arr, low, high):
if low >= high:
return
mid = self.partition(arr, low, high)
self.quickSort(arr, low, mid-1)
self.quickSort(arr, mid+1, high)
func partition(nums []int, low, high int) int {
rand.Seed(time.Now().UnixNano())
pivotIdx := rand.Intn(high-low) + low
nums[low], nums[pivotIdx] = nums[pivotIdx], nums[low]
pivot := nums[low]
left, right := low, high
for left < right {
for left < right && nums[right] >= pivot {
right--
}
nums[left] = nums[right]
for left < right && nums[left] <= pivot {
left++
}
nums[right] = nums[left]
}
nums[left] = pivot
return left
}
func quickSort(nums []int, low, high int) {
if low >= high {
return
}
mid := partition(nums, low, high)
quickSort(nums, low, mid-1)
quickSort(nums, mid+1, high)
}
时间复杂度:O(NlogN)
空间复杂度:O(logN)
快速排序
class Solution {
public:
void swap(vector<int>& nums, int i, int j){
int tmp = nums[i];
nums[i] = nums[j];
nums[j] = tmp;
}
void fastSort(vector<int>& nums, int start, int end){
if (start >= end) return;
int pivot = nums[start + ((end - start)/2)];
int l = start;
int r = end;
while(l <= r){
while(nums[l] < pivot)l++;
while(nums[r] > pivot)r--;
if(l <= r){
swap(nums,l,r);
l++;
r--;
}
}
fastSort(nums,start,r);
fastSort(nums,l,end);
}
vector<int> sortArray(vector<int>& nums) {
fastSort(nums, 0, nums.size()-1);
return nums;
}
};
快速排序
var quickSort = function(arr, start, end){
if(start >= end) return;
let left = start;
let right = end;
let pivot = arr[left];
while(left < right){
//顺序很重要,要先从右边开始找,因为pivot是arr[left],从右边开始找可以保证数据不丢失
while((left < right) && arr[right] >= pivot) right--;
if(arr[right] < pivot){
arr[left] = arr[right];
}
//再找左边
while((left < right) && arr[left] <= pivot) left++;
if(arr[left] > pivot){
arr[right] = arr[left];
}
}
arr[left] = pivot;
quickSort(arr, start, left - 1);
quickSort(arr, left + 1, end);
}
var sortArray3 = function(nums) {
quickSort(nums, 0, nums.length - 1);
return nums;
};
时间复杂度:O(nlgn)
空间复杂度:O(nlgn)
class Solution(object):
def sortArray(self, nums):
"""
:type nums: List[int]
:rtype: List[int]
"""
self.quick_sort (0, len(nums)-1, nums);
return nums;
def quick_sort(self, start, end, arr):
if start >= end:
return;
pos = self.partition(start, end, arr);
self.quick_sort(start, pos-1, arr);
self.quick_sort(pos+1,end, arr);
def partition(self,start, end, arr):
index = start;
ran = randint(start,end);
self.swap(ran, end, arr);
pivot = arr[end];
for i in range(start,end):
if arr[i] < pivot:
self.swap(index, i,arr);
index +=1;
self.swap(index, end, arr);
return index;
def swap(self, left, right, arr):
arr[left], arr[right] = arr[right], arr[left]
return arr;
时间复杂度:o(nlogn)
/*
quick sort:
O(n^2) time when it is reversed
the best case:
[half] pivot [half]
T(n) = O(n) + 2*T(n/2)
O(nlogn)
avg case:
O(nlogn)
Space:
avg: O(logn)
worst: O(n)
The average case space used will be of the order O(log n) .
The worst case space complexity becomes O(n) ,
when the algorithm encounters its worst case where for
getting a sorted list, we need to make n recursive calls.
*/
class Solution {
public int[] sortArray(int[] nums) {
shuffle(nums);
quickSort(nums, 0, nums.length - 1);
return nums;
}
// O(n) time
private void shuffle(int[] nums) {
Random rand = new Random();
for (int i = 0; i < nums.length; i++) {
int randomIndexToSwap = rand.nextInt(nums.length);
swap(nums, i, randomIndexToSwap);
}
}
private void quickSort(int[] nums, int start, int end) {
if (start >= end) {
return;
}
int pivotIndex = start, left = start + 1, right = end;
while (left <= right) {
if (nums[left] > nums[pivotIndex] && nums[right] <= nums[pivotIndex]) {
swap(nums, left, right);
}
if (nums[left] <= nums[pivotIndex]) {
left++;
}
if (nums[right] > nums[pivotIndex]) {
right--;
}
}
swap(nums, pivotIndex, right);
if (right - 1 - start + 1 >= end - right - 1 + 1) {
quickSort(nums, right + 1, end);
quickSort(nums, start, right - 1);
} else {
quickSort(nums, start, right - 1);
quickSort(nums, right + 1, end);
}
}
private void swap(int[] nums, int i, int j) {
int temp = nums[i];
nums[i] = nums[j];
nums[j] = temp;
}
}
归并排序
var sortArray = function(nums) {
return splitList(nums)
};
// 拆分数组
function splitList (list) {
let len = list.length
if(len === 1) return list
let mid = len >> 1
let left = list.slice(0, mid)
let right = list.slice(mid)
return mergeList(splitList(left), splitList(right))
}
// 合并, 排序数组
function mergeList (left, right) {
let res = []
let il = 0, lenl = left.length
let ir = 0, lenr = right.length
while(il < lenl && ir < lenr){
if(left[il] < right[ir]){
res.push(left[il++])
} else {
res.push(right[ir++])
}
}
while(il < lenl){
res.push(left[il++])
}
while(ir < lenr){
res.push(right[ir++])
}
return res
}
时间复杂度: O(nlogn)
空间复杂度: O(n)
class Solution:
def partition(self,nums: List[int], l:int, r:int) -> int:
p = randint(l,r)
nums[r],nums[p] = nums[p],nums[r]
i = l - 1
for j in range(l,r):
if nums[j] < nums[r]:
i = i + 1
nums[i],nums[j] = nums[j],nums[i]
i = i + 1
nums[i],nums[r] = nums[r],nums[i]
return i
def quicksort(self,nums: List[int], l:int, r:int) -> List[int]:
if r-l <= 0:
return
mid = self.partition(nums,l,r)
self.quicksort(nums,l,mid-1)
self.quicksort(nums,mid+1,r)
def sortArray(self, nums: List[int]) -> List[int]:
self.quicksort(nums,0,len(nums)-1)
return nums
class Solution {
public:
vector<int> sortArray(vector<int>& nums) {
sort(nums.begin(), nums.end());
return nums;
}
};
function sortArray(arr, left, right) {
var len = arr.length,
partitionIndex,
left = typeof left != 'number' ? 0 : left,
right = typeof right != 'number' ? len - 1 : right;
if (left < right) {
partitionIndex = partition(arr, left, right);
sortArray(arr, left, partitionIndex-1);
sortArray(arr, partitionIndex+1, right);
}
return arr;
}
function partition(arr, left ,right) { // 分区操作
var pivot = left, // 设定基准值(pivot)
index = pivot + 1;
for (var i = index; i <= right; i++) {
if (arr[i] < arr[pivot]) {
swap(arr, i, index);
index++;
}
}
swap(arr, pivot, index - 1);
return index-1;
}
function swap(arr, i, j) {
var temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
-
class Solution:
# 归并排序,采用分治的思想
def merge_sort(self, nums, l, r):
if l == r:
return
# 中点
mid = (l + r) // 2
# 中点左侧的数组归并排序
self.merge_sort(nums, l, mid)
# 中点右侧的数组归并排序
self.merge_sort(nums, mid + 1, r)
tmp = []
i, j = l, mid + 1
# 判断左右两边数组元素大小,然后放到tmp中
while i <= mid or j <= r:
if i > mid or (j <= r and nums[j] < nums[i]):
tmp.append(nums[j])
j += 1
else:
tmp.append(nums[i])
i += 1
nums[l: r + 1] = tmp
def sortArray(self, nums: List[int]) -> List[int]:
self.merge_sort(nums, 0, len(nums) - 1)
return nums
class Solution:
def sortArray(self, nums: List[int]) -> List[int]:
def partition(arr, low, high):
pivot_idx = random.randint(low, high) # 随机选择pivot
arr[low], arr[pivot_idx] = arr[pivot_idx], arr[low] # pivot放置到最左边
pivot = arr[low] # 选取最左边为pivot
left, right = low, high # 双指针
while left < right:
while left<right and arr[right] >= pivot: # 找到右边第一个<pivot的元素
right -= 1
arr[left] = arr[right] # 并将其移动到left处
while left<right and arr[left] <= pivot: # 找到左边第一个>pivot的元素
left += 1
arr[right] = arr[left] # 并将其移动到right处
arr[left] = pivot # pivot放置到中间left=right处
return left
def quickSort(arr, low, high):
if low >= high: # 递归结束
return
mid = partition(arr, low, high) # 以mid为分割点,右边元素>左边元素
quickSort(arr, low, mid-1) # 递归对mid两侧元素进行排序
quickSort(arr, mid+1, high)
quickSort(nums, 0, len(nums)-1) # 调用快排函数对nums进行排序
return nums
function sortArray(nums: number[]): number[] {
for (let i = 0; i < nums.length - 1; i++) {
let minIndex = i;
for (let j = i; j < nums.length - 1; j++) {
if (nums[minIndex] > nums[j + 1]) {
minIndex = j + 1;
}
}
if (minIndex !== i) {
const temp = nums[i];
nums[i] = nums[minIndex];
nums[minIndex] = temp;
}
}
return nums;
};
Python3 Code:
class Solution:
def randomized_partition(self, nums, l, r):
pivot = random.randint(l, r)
nums[pivot], nums[r] = nums[r], nums[pivot]
i = l - 1
for j in range(l, r):
if nums[j] < nums[r]:
i += 1
nums[j], nums[i] = nums[i], nums[j]
i += 1
nums[i], nums[r] = nums[r], nums[i]
return i
def randomized_quicksort(self, nums, l, r):
if r - l <= 0:
return
mid = self.randomized_partition(nums, l, r)
self.randomized_quicksort(nums, l, mid - 1)
self.randomized_quicksort(nums, mid + 1, r)
def sortArray(self, nums: List[int]) -> List[int]:
self.randomized_quicksort(nums, 0, len(nums) - 1)
return nums
复杂度分析
令 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