思路:
题目的主要信息:
- 给数组排序
- 不要求稳定与否
就十分普通的排序问题,不考虑时间空间,常见的排序算法都可以,以下介绍几种。
方法一:sort函数(快排)
具体做法:
直接调用sort函数排序。
class Solution {
public:
vector<int> MySort(vector<int>& arr) {
sort(arr.begin(), arr.end()); //直接调用排序函数
return arr;
}
};复杂度分析:
- 时间复杂度:
,快排的时间复杂度
- 空间复杂度:
,没有额外空间
方法二:冒泡排序法(超时)
具体做法:
两层循环,内循环依次比较前后元素的大小,若是大的在前,则交换二者顺序
class Solution {
public:
vector<int> MySort(vector<int>& arr) {
for(int i = 0; i < arr.size(); i++)
for(int j = 1; j < arr.size(); j++)
if(arr[j] < arr[j - 1]){//比较并冒泡
int temp = arr[j]; //交换
arr[j] = arr[j - 1];
arr[j - 1] = temp;
}
return arr;
}
};复杂度分析:
- 时间复杂度:
,两层循环
- 空间复杂度:
,除了常数变量,没有额外空间、
方法三:归并排序法
归并排序利用了分治的思想来对序列进行排序。对一个长为n的待排序的序列,我们将其分解成两个长度为n/2的子序列。每次先递归调用函数使两个子序列有序,然后我们再线性合并两个有序的子序列使整个序列有序。
class Solution {
public:
vector<int> temp;
void mergeSort(vector<int>& arr, int l, int r) {
if (l >= r)
return;
int mid = (l + r) / 2; //中间划分
mergeSort(arr, l, mid); //排序两边
mergeSort(arr, mid + 1, r);
int i = l, j = mid + 1;
int cnt = 0;
//合并
while (i <= mid && j <= r) { //依次比较,先取较小值
if (arr[i] <= arr[j])
temp[cnt++] = arr[i++];
else
temp[cnt++] = arr[j++];
}
while (i <= mid) //剩余的元素
temp[cnt++] = arr[i++];
while (j <= r)
temp[cnt++] = arr[j++];
for (int i = 0; i < r - l + 1; ++i)
arr[i + l] = temp[i];
}
vector<int> MySort(vector<int>& arr) {
temp.resize(arr.size(), 0);
mergeSort(arr, 0, arr.size() - 1);
return arr;
}
};复杂度分析:
- 时间复杂度:
,递归公式为
,故复杂度为
- 空间复杂度:
,借助了temp数组
方法四:堆排序
具体做法:
使用priority_queue模拟大根堆,将数组中的元素依次入堆,然后因为是大数在堆顶,依次出堆时需要逆序放回数组中。
class Solution {
public:
vector<int> MySort(vector<int>& arr) {
priority_queue<int> q; //大根堆
for(int i = 0; i < arr.size(); i++) //入堆
q.push(arr[i]);
for(int i = arr.size() - 1; i >= 0; i--){ //大的在顶部,所以逆序
arr[i] = q.top();
q.pop();
}
return arr;
}
};复杂度分析:
- 时间复杂度:
,元素入堆为
,一共n个元素
- 空间复杂度:
,堆的大小

京公网安备 11010502036488号