977. 有序数组的平方(这题可以练习一下各种排序 双指针)

977. 有序数组的平方

给你一个按 非递减顺序 排序的整数数组 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 ;
    }

};

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值