算法day3 有序数组的平方

问题描述

思路一:暴力解
通过for循环更新nums数组的值,随后对nums数组采用快速排序,最后将其返回。

代码如下

void quick_sort(vector<int> &a,int low,int high){
       if(low>=high){ //边界检查
        return ;
       }
        int i = low;
        int j = high;
        int temp = a[i];
        while(i<j){
            while(i<j&&a[j]>=temp) j--;
            a[i] = a[j];
            while(i<j&&a[i]<=temp) i++;
            a[j] = a[i];
        } // i==j
        a[i] = temp;
        quick_sort(a,low,i-1);
        quick_sort(a,i+1,high);

}

vector<int> sortedSquares(vector<int>& nums) {
    for(int &k:nums){
        k *= k;
    }
    quick_sort(nums,0,nums.size()-1);

    return nums;
}

扩展:快速排序
快速排序采用分治的思想,选取一个基准元素(pivot),将数组分为两部分,左边元素小于等于pivot,右边元素大于等于pivot,随后不断地对左右的子数组递归,直到数组的长度为1或0。pivot的选取可以是数组的任意位置的元素,为了方便起见,我这里选取了首元素作为pivot。在while循环中,将两侧指针指向的元素与pivot不断地比较,大者更新至pivot右侧,小者更新至左侧,待循环结束得到此轮的pivot,它已存储在最终位置。随后对子数组进行递归,最终得到最后的序列。

快排时间复杂度:O(nlogn)
快排空间复杂度:O(logn)

视频讲解可以访问此链接:https://www.bilibili.com/video/BV1Uh4y1F7FF/?p=4&spm_id_from=333.1007.top_right_bar_window_history.content.click&vd_source=8873a0b6bc1e6eaf728fd129a1abaa30

思路一时间复杂度:O(nlogn)
思路一空间复杂度:O(logn)

思路二:双指针
观察以下例子:

  nums[3] = {1,2,3} --->{1,4,9}
  nums[3] = {-1,0,1}--->{1,0,1}
  nums[3] = {-5,0,1}--->{25,0,1}

我们可以发现对于非递减数组平方后的值,其较大值出现于右侧或两侧,所以我们可以设置左右两侧的指针i,j,设置一个指针k指向新创建的数组result的末尾值,随后在循环条件下不断地比较i,j指针指向的元素,将较大者赋值给k指向的位置,随后前移k,同时前移(后移)j(i)指针,直至循环结束,返回result。

代码如下

  vector<int> sortedSquares(vector<int>& nums) {
    vector<int> result(nums.size()); //这里一定要初始化他的长度,否则会导致后续的赋值操作越界
    int k = nums.size()-1; //获取末尾元素的位序
    int i = 0,j = nums.size()-1;
    for(;i<=j;){
        if( nums[i]*nums[i]> nums[j]*nums[j] ){
            result[k--] = nums[i] * nums[i];
            i++;
        }else{
            result[k--] = nums[j] * nums[j];
            j--;
        }
    }
  
    return result;
}

思路二时间复杂度:O(n)
思路二空间复杂度:O(n)

END

posted on 2025-04-06 16:39  sakura430  阅读(10)  评论(0)    收藏  举报