给你一个按 非递减顺序 排序的整数数组 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 <= nums.length <= 104
-104 <= nums[i] <= 104
nums
已按 非递减顺序 排序
进阶:
- 请你设计时间复杂度为
O(n)
的算法解决本问题
希尔排序(36ms)
class Solution {
public:
vector<int> sortedSquares(vector<int>& nums) {
for( int i = 0 ;i < nums.size() ;++i){
nums[i] = (int)pow(nums[i],2);
}
int Sedgewick[] = {929, 505, 209, 109, 41, 19, 5, 1, 0}; //增量序列
int Si ,i;
for( Si = 0; Sedgewick[Si] > 0 && Sedgewick[Si] >= nums.size() ; Si++){}
for( int D = Sedgewick[Si] ; D > 0 ; D = Sedgewick[++Si]){
for( int N = D ;N < nums.size() ;++N){
int Tmp = nums[N] ;
for( i = N ; i - D >= 0 && Tmp < nums[i - D] ;i = i - D ){
nums[i] = nums[i-D] ;
}
nums[i] = Tmp ;
}
}
return nums ;
}
};
冒泡排序(超时)
class Solution {
public:
vector<int> sortedSquares(vector<int>& nums) {
int N = nums.size() ;
for( int i = 0;i < N ;++i){
nums[i] = (int)pow( nums[i],2 );
}
int Flag ,Tmp ;
for( int i = 1;i < nums.size() ;++i,N-=1){
Flag = 1 ;
for( int j = 1; j <= N - 1 ;j++){
if(nums[j] < nums[j-1]){
Tmp = nums[j-1];
nums[j-1] = nums[j] ;
nums[j] = Tmp ;
Flag = 0 ;
}
}
if(Flag)
break ;
}
return nums ;
}
};
插入排序(勉强通过 还是没有增量序列的希尔快 1908 ms)
class Solution {
public:
vector<int> sortedSquares(vector<int>& nums) {
for( int i = 0 ;i < nums.size() ;++i){
nums[i] = (int)pow(nums[i],2);
}
int i ;
for( int N = 1 ;N < nums.size() ;++N){
int Tmp = nums[N] ;
for( i = N ; i - 1 >= 0 && Tmp < nums[i - 1] ;i = i - 1 ){
nums[i] = nums[i-1] ;
}
nums[i] = Tmp ;
}
return nums ;
}
};
归并排序 递归写法(没测试 )
#include<stdio.h>
int B[5] ;
void Merge(int *A,int *B,int Left,int Center,int Right){
int BStart = Center + 1 ;
int index = Left ;
int Len = Right - Left + 1;
while( Left <= Center && BStart <= Right){
if(A[Left] < A[BStart])
B[index++] = A[Left++];
else
B[index++] = A[BStart++];
}
while(Left <= Center){
B[index++] = A[Left++];
}
while(BStart <= Right){
B[index++] = A[BStart++];
}
for( int i = 0;i < Len ;i++,Right--){
A[Right] = B[Right];
}
}
void Msort( int * A,int *B ,int Left,int Right){
if(Left < Right){
int Center = (Left + Right) / 2 ;
Msort(A, B , Left , Center );
Msort(A, B , Center + 1 , Right);
Merge(A,B,Left,Center,Right);
}
}
void Merge_Sort(int *A, int *B,int Size){
Msort(A,B,0,Size - 1 );
}
双指针1(24ms)
class Solution {
public:
vector<int> sortedSquares(vector<int>& nums) {
int i ;
vector<int>Vec(nums.size());
for( i = 0;i < nums.size() ;++i){
if(nums[i] >= 0)
break ;
}
if( i == 0){
for( int j = 0;j < nums.size() ;j++){
nums[j] = nums[j] * nums[j];
}
return nums ;
}else{
int Negative = i - 1,Positive = i,index = 0 ;
while(Negative >= 0 && Positive < nums.size()){
if( abs(nums[Negative]) < nums[Positive])
Vec[index++] = pow(nums[Negative--],2) ;
else
Vec[index++] = pow(nums[Positive++],2);
}
while(Negative >= 0){
Vec[index++] = pow(nums[Negative--],2);
}
while(Positive < nums.size()){
Vec[index++] = pow(nums[Positive++],2);
}
}
return Vec ;
}
};
双指针2(20ms)
class Solution {
public:
vector<int> sortedSquares(vector<int>& nums) {
vector<int> Vec(nums.size());
int Front = 0 ;
int Last = nums.size() - 1 ;
int index = Vec.size() - 1 ;
while(Front <= Last){
if( pow(nums[Front],2) > pow(nums[Last],2 ) )
Vec[index--] = pow(nums[Front++],2);
else
Vec[index--] = pow( nums[Last--],2) ;
}
return Vec ;
}
};
评价与理解:这道题我第一次做是采用的是希尔排序 ,显然这题不是让你用排序做的
双指针1类似于归并排序的思想:分而治之的思想 先给数组分为两部分 然后治
双指针2 就是技巧了 让两个指针一个在开始位置一个在末尾位置
先考虑一种情况 数组全为正 这种情况不用想 这种情况都不用比较两个指针 因为一个正数<一个正数他的平方小于那个正数 另一种情况有负数 这种情况也是分而治之 治的思想
补充一下 堆排序 表排序 基数排序 我没试 快排写了没过 我自己看了一下没发现什么问题 把快排代码先放下面:
快速排序(没过)
class Solution {
public:
vector<int> sortedSquares(vector<int>& nums) {
for( int i = 0 ;i < nums.size() ;++i){
nums[i] = (int)pow(nums[i],2);
}
Quick_Sort(nums,0,nums.size()-1);
return nums ;
}
void Quick_Sort(vector<int> &nums,int Left,int Right){
if( 300 <= Right - Left){
int Low = Left ,High = Right - 1;
int Meddle = Median(nums,Left,Right);
while(1){
while(nums[++Low] < Meddle);
while( nums[--High] > Meddle);
if(Low < High)
Swap(nums,Low,High);
else
break ;
}
Swap(nums,Low,Right -1 );
Quick_Sort(nums,Left,Low-1);
Quick_Sort(nums,Low + 1 ,Right);
}else{
Insert_Sort(nums,Left,Right - Left + 1 );
}
}
int Median(vector<int> &nums,int Left,int Right){
int Center = (Left + Right) / 2 ;
if(nums[Left] > nums[Center])
Swap(nums,Left,Center);
if(nums[Left] > nums[Right])
Swap(nums,Left,Right);
if( nums[Center] > nums[Right])
Swap(nums,Center,Right);
return nums[Right - 1];
}
void Insert_Sort(vector<int> & nums , int Left ,int Right){
int Tmp ,j;
for( int i = Left; i < Right;++i){
Tmp = nums[i];
for( j = i; j - 1 >= Left && nums[j-1] > Tmp ;j--){
nums[j] = nums[j-1] ;
}
nums[j] = Tmp ;
}
}
void Swap(vector<int> & nums,int A ,int B){
int Tmp = nums[A];
nums[A] = nums[B];
nums[B] = Tmp ;
}
};