题目链接

题目描述

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

示例

示例1:

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

提示

  • 1 <= nums.length <= 10
  • -10 <= nums[i] <= 10
  • nums 已按 非递减顺序 排序

    思路

    思路1:排序

    平方后排序。

    思路2:双指针

    对于一个数组 nums 来说,平方的最大值只能在头部或尾部产生。考虑一般情况,即数组中有负数,0,和正数,维护两个指针 left = 0right = n - 1

  • 两个指针相向移动的过程中,比较两数平方,将较大者加入数组 ans 中。

  • 数组 ans 逆序遍历。

一点优化:比较平方 if(nums[left] * nums[left] < nums[right] * nums[right]) 可以优化为 if(-nums[left] < nums[right]),可以减少乘法运算。
此做法的正确性是可以证明的:
为了表示简单,我们设 0977-有序数组的平方 - 图1,分类讨论:

  • 0977-有序数组的平方 - 图2,由 nums 非递减可知 0977-有序数组的平方 - 图3,此时恒有 0977-有序数组的平方 - 图4,且 0977-有序数组的平方 - 图5
  • 0977-有序数组的平方 - 图6,由 nums 非递减可知 0977-有序数组的平方 - 图7,此时恒有 0977-有序数组的平方 - 图8,且 0977-有序数组的平方 - 图9
  • 0977-有序数组的平方 - 图10 异号,则只有 0977-有序数组的平方 - 图11,若 0977-有序数组的平方 - 图12,有 0977-有序数组的平方 - 图13;若 0977-有序数组的平方 - 图14,有 0977-有序数组的平方 - 图15

综上所诉,两者是等价的。

题解

思路2:双指针

  1. class Solution {
  2. public:
  3. vector<int> sortedSquares(vector<int>& nums) {
  4. int n = nums.size();
  5. int left = 0, right = n - 1;
  6. int i = n - 1;
  7. vector<int> ans(n);
  8. while (left <= right) {
  9. if (-nums[left] < nums[right]) {
  10. ans[i--] = nums[right] * nums[right];
  11. --right;
  12. } else {
  13. ans[i--] = nums[left] * nums[left];
  14. ++left;
  15. }
  16. }
  17. return ans;
  18. }
  19. };

复杂度分析

思路2:双指针

  • 时间复杂度:0977-有序数组的平方 - 图16
  • 空间复杂度:0977-有序数组的平方 - 图17