01_数组_03_非递减数组的平方

https://leetcode.cn/problems/squares-of-a-sorted-array/description/

内容

给你一个按 非递减顺序 排序的整数数组 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) 的算法解决本问题

代码(后边界起遍历)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
class Solution {
public:
vector<int> sortedSquares(vector<int>& nums) {
int left = 0;
int right = nums.size() - 1;
vector<int> newnums(nums.size());
for (int i = newnums.size() - 1; i >= 0; --i)
{
int a = nums[left] > 0 ? nums[left] : -nums[left];
int b = nums[right] > 0 ? nums[right] : -nums[right];
if (a >= b)
{
newnums[i] = a * a;
++left;
}
else
{
newnums[i] = b * b;
--right;
}
}
return newnums;
}
};

思想

数组其实是有序的, 只不过负数平方之后可能成为最大数了。

那么数组平方的最大值就在数组的两端,不是最左边就是最右边,不可能是中间。

此时可以考虑双指针法了,left 指向起始位置,right 指向终止位置。

定义一个新数组newnums,和原数组一样的大小,让 i 指向新数组终止位置。

如果A[left] * A[left] < A[right] * A[right] 那么newnums[i] = A[left] * A[left]; 。反之= A[right] * A[right]

复杂度分析

相比于双层for循环的暴力解法,快慢指针的方法可以让时间复杂度降为O(n)O(n)
空间复杂度O(n)O(n)