给你一个按 非递减顺序 排序的整数数组 nums,返回 每个数字的平方 组成的新数组,要求也按 非递减顺序 排序。
示例 1:
输入:nums = [-4,-1,0,3,10]
输出:[0,1,9,16,100]
解释:平方后,数组变为 [16,1,0,9,100]
排序后,数组变为 [0,1,9,16,100]
示例 2:
输入:nums = [-7,-3,2,3,11]
输出:[4,9,9,49,121]
面对这样的题目,先把原来的数据平方后,有几种算来进行排序
1.直接插入排序:
class Solution {
public:
vector<int> sortedSquares(vector<int>& nums) {
//直接插入排序
int i, j;
//平方后的数组
for (i = 0; i < nums.size(); i++)
{
nums[i] = nums[i] * nums[i];
}
int temp = nums[0];
for (i = 1; i < nums.size(); i++)
{
if (nums[i] < nums[i - 1])//小的做为哨兵
{
temp = nums[i];//复制为哨兵
for (j = i - 1; j >= 0 && nums[j] > temp ; j--)
{
nums[j + 1] = nums[j];
}
nums[j+1] = temp;
}
}
return nums;
}
};
结果同样的不尽如人意。
此算法的时间复杂度为O(n^2)
2.折半插入排序
class Solution {
public:
vector<int> sortedSquares(vector<int>& nums) {
//直接插入排序
int i, j,low,high,mid;
//平方后的数组
for (i = 0; i < nums.size(); i++)
{
nums[i] = nums[i] * nums[i];
}
int temp = nums[0];
for (i = 1; i < nums.size(); i++)
{
low=0;
high=i-1;
mid=(low+high)/2;
if (nums[i] < nums[i - 1])//判断是否比前一个小,如果小就插入
{
temp = nums[i];//复制为哨兵,进行判断
while(low<=high)
{
if(temp>=nums[mid])
{
low=mid+1;
}
else
{
high=mid-1;
}
mid = (low + high) / 2;
}
for (j = i - 1; j>high ; j--)
{
nums[j + 1] = nums[j];
}
nums[high+1] = temp;
}
}
return nums;
}
};
折半插入排序插入排序也确实会比直接插入快了点。折半插入排序只是减少了比较次数,时间复杂度还是O(n^2)
3.希尔排序时间复杂度约为O(n^1.3), 最坏情况下时O(n^2)
class Solution {
public:
vector<int> sortedSquares(vector<int>& nums) {
int step,i,j,temp;
//平方后的数组
for (i = 0; i < nums.size(); i++)
{
nums[i] = nums[i] * nums[i];
}
//希尔排序
for(step=nums.size()/2;step>0;step/=2)//步长变化
{
for(i=step;i<nums.size();i++)
{
temp=nums[i];
for(j=i-step;j>=0 && temp<nums[j];j-=step)
{
nums[j+step]=nums[j];//后移
}
nums[j+step]=temp;
}
}
return nums;
}
};
结果有了显著的提升
采用空间换时间双指针的方法,优点类似与归并排序
class Solution {
public:
vector<int> sortedSquares(vector<int>& nums) {
int pos,i,j;
vector<int> temp(nums.size());
for(i=0,j=nums.size()-1,pos=nums.size()-1;i<=j;)
{
if(nums[i]*nums[i]>nums[j]*nums[j])
{
temp[pos--]=nums[i]*nums[i];
i++;
}
else
{
temp[pos--]=nums[j]*nums[j];
j--;
}
}
return temp;
}
};
空间复制度为O(n)
效果显而易见
4.快速排序
class Solution {
public:
vector<int> sortedSquares(vector<int>& nums) {
for(int i=0;i<nums.size();i++)
{
nums[i]=nums[i]*nums[i];
}
QuickSort(nums,0,nums.size()-1);
return nums;
}
void QuickSort(vector<int>& nums,int low,int high)
{
if(low<high)
{
int pivotpos=Patition(nums,low,high);
QuickSort(nums,low,pivotpos-1);
QuickSort(nums,pivotpos+1,high);
}
}
//快速排序
int Patition(vector<int>& number,int low,int high)
{
int pivot=number[low];//枢纽
while(low<high)
{
while(low<high && number[high]>=pivot)
{
high--;
}
number[low]=number[high];//置换
while(low<high && number[low]<=pivot)
{
low++;
}
number[high]=number[low];
}
number[low]=pivot;
return low;
}
};
5.归并排序
#include <iostream>
#include<vector>
using namespace std;
//归并排序
void Merge(vector<int>& nums,int low,int mid,int high)
{
int* temp = (int*)malloc(nums.size());
int count, i, j;
for (count = low; count <=high; count++)
{
temp[count] = nums[count];
}
for (i = low, j = mid + 1, count = i; i <= mid&&j <= high; count++)
{
if (temp[i] <= temp[j])
{
nums[count] = temp[i++];
}
else
{
nums[count] = temp[j++];
}
}
while (i <= mid)
{
nums[count++] = temp[i++];
}
while (j <= high)
{
nums[count++] = temp[j++];
}
}
void MergeSort(vector<int>& nums, int low, int high)
{
if (low < high)
{
int mid = (low + high) / 2;
MergeSort(nums, low, mid);
MergeSort(nums, mid + 1, high);
Merge(nums, low, mid, high);
}
}
int main()
{
//nums = [-4, -1, 0, 3, 10]
vector<int> nums = { 16,1,0,100,10 };
MergeSort(nums, 0, 4);
for (int i = 0; i < 5; i++)
{
printf(" % d\t", nums[i]);
}
}
leetcode中超时了,但是自己测试了一下没啥问题
6.堆排序
void HeadAdjust(vector<int>& nums, int k, int len)
{
int i, j;
nums[0] = nums[k];
for (i = 2 * k; i <= len; i*=2)
{
if (i < len-1 && nums[i] < nums[i + 1])
{
i++;
}
if (nums[0] >= nums[i])
{
break;
}
else
{
nums[k] = nums[i];
k = i;
}
}
nums[k] = nums[0];
}
//大根堆
void BuildMaxHeap(vector<int>& nums,int len)
{
int i = 0;
for ( i= len / 2; i > 0; i--)
{
HeadAdjust(nums, i, len);
}
}
void HeapSort(vector<int>& nums, int len)
{
int i,temp=0;
BuildMaxHeap(nums, len);//初始化大根堆
for ( i= len-1; i > 1; i--)
{
temp = nums[i];
nums[i] = nums[1];
nums[1] = temp;
HeadAdjust(nums, 1, i - 1);
}
}
int main()
{
//nums = [-4, -1, 0, 3, 10]
vector<int> nums = { 0,53,17,78,9,45,65,87,32 };
HeapSort(nums,nums.size());
//MergeSort(nums, 0, 7);
for (int i = 1; i < 9; i++)
{
printf(" %d\t", nums[i]);
}
}