有序数组平方排序

这篇博客探讨了两种解决有序数组平方排序的方法。第一种是直接平方后进行排序,时间复杂度为O(nlogn),空间复杂度为O(logn)。第二种方法利用双指针和归并排序思想,时间复杂度降低到O(n),空间复杂度为O(1)。这两种方法都针对已排序数组的特点进行了优化。
摘要由CSDN通过智能技术生成

有序数组平方排序

主要用来练习排序算法。

问题描述:

给你一个按 非递减顺序 排序的整数数组 nums,返回 每个数字的平方 组成的新数组,要求也按 非递减顺序 排序。

示例:
输入:nums = [-4,-1,0,3,10]
输出:[0,1,9,16,100]
解释:平方后,数组变为 [16,1,0,9,100]
排序后,数组变为 [0,1,9,16,100]

算法分析:

  1. 方案一:直接平方后,再进行排序
class Solution{
public:
		vector<int> sortedSquares(vector<int>& nums){
				vector<int> abs;
				for(int num:nums){
						abs.push_back(num*num); //在push_back()函数是在尾部添加值
				}
				sort(abs.begin(),abs.end());//排序,从容器第一个数开始,到最后一个数,默认升序
				return abs;
		}
};

复杂度分析

时间复杂度: O ( n log ⁡ n ) O(n \log n) O(nlogn),其中 n 是数组 n u m s nums nums 的长度。
空间复杂度: O ( log ⁡ n ) O(\log n) O(logn)。除了存储答案的数组以外,但是需要 O ( log ⁡ n ) O(\log n) O(logn) 的栈空间进行排序。
链接:来源


  1. 方案二:使用双指针
    方法一没有利用数组已经按照升序排序这个条件。显然,数组分为正负两部分,而且每部分都是有序的,这样就可以转换成两个有序数组进行<归并排序>的方法。
    思路:
    先找出数组的分界线zero,然后 n u m s [ 0 ] nums[0] nums[0] n u m s [ z e r o ] nums[zero] nums[zero]全为负数,平方后, z e r o zero zero左边的数组降序排序,右边数组为升序排序,使用<归并排序>排序更有效。具体地,使用两个指针分别指向位置 z e r o zero zero z e r o + 1 zero+1 zero+1,每次比较两个指针对应的数,选择较小的那个放入答案并移动指针。当某一个指针移至边界时,将另一个指针按序放入答案。
class Solution {
	public vector<int> sortedSquares(vector<int>& nums) {
		int n = nums.size();
		int negative = -1;
		for(int i = 0;i < n; ++i) {
			if (nums[i] < 0)
				negative = i;
			else 
				break; //找到分解点
		}
		//归并排序
		vector<int> ans;
		int i = negativel
		int j = negative + 1;
		while (i>=0 || j<n) {
			if(i < 0)  {//全是正数
				ans.push_back(nums[j] * nums[j]);
				j++;
			}
			else if (j==n){//全为负数
				ans.push_back(nums[i] * nums[i];
				i--;
			}
			else if(nums[i] * nums[i] < nums[j] * nums[j]){
				ans.push_back(nums[i] * nums[i]);
				i--;
			}
			else {
				ans.push_back(nums[j] * nums[j]);
				j++;
			}
		}
	}
};

复杂度分析:
时间复杂度: O ( n ) O(n) O(n),其中 n是数组 n u m s nums nums的长度。
空间复杂度: O ( 1 ) O(1) O(1)。除了存储答案的数组以外,只需要维护常量空间。


另一个思路是,可以使用两个指针分别指向位置 0 和 n-1,每次比较两个指针对应的数,选择较大的那个逆序放入答案并移动指针,这种方法无需处理某一指针移动至边界的情况。
class Solution {
	public:vector<int>sortedSquares(vector<int>& nums){
		int n = nums.size();
		vector<int> ans(n);
		for(int i = 0,j = n-1,pos = n-1;i < j;){
			if (nums[i] * nums[i] > nums[j] * nums[j]){
				ans[pos] = nums[i] * nums[i];
				i++;
			}
			else {
				ans[pos] = nums[j] * nums[j];
				j--;
			}
			pos--;
		}
		return ans;
	}
};
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值