LC 0977.Squares of a Sorted Array

题目描述

这是 LeetCode 上的 977. 有序数组的平方 ,难度为简单

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

示例 1:

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

示例 2:

1
2
输入:nums = [-7,-3,2,3,11]
输出:[4,9,9,49,121]

提示:

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

进阶:

  • 请你设计时间复杂度为 O(n) 的算法解决本问题

解答

方法一:排序

最容易想到的方法是先平方之后再进行排序,排序可以选择的算法很多,这里采用 Java 内置的排序算法进行排序。

1
2
3
4
5
6
7
8
9
class Solution {
public int[] sortedSquares(int[] nums) {
for (int i = 0; i < nums.length; ++i) {
nums[i] *= nums[i];
}
Arrays.sort(nums);
return nums;
}
}
  • 时间复杂度\(O(n \log n)\)Java 内置的排序算法 Arrays.sort 的时间复杂度为 \(O(n \log n)\) ,遍历数组的时间复杂度为 \(O(n)\),其中 n 为数组的长度。

  • 空间复杂度\(O(n)\)Java 内置的排序算法的空间复杂度为 n ,其中 n 为数组的长度。

方法二:双指针

根据题目的说明,已知原数组已经按照非递减的顺序排序,所以可以使用双指针来遍历数组,类似于二次函数的图像,最大值在两端取到,所以从最大值开始排序,使用指针 i 和指针 j 分别指向原数组的两端,比较它们的值,将较大的值放入目标数组 res 的末端,并向前移动放入的数的指针,最终遍历结束即可。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
class Solution {
public int[] sortedSquares(int[] nums) {
int[] res = new int[nums.length];
int i = 0, j = nums.length - 1;
int pos = nums.length - 1;
while (i <= j) {
int a = nums[i] * nums[i], b = nums[j] * nums[j];
if (a > b) {
res[pos--] = a;
++i;
} else {
res[pos--] = b;
--j;
}
}
return res;
}
}
  • 时间复杂度\(O(n)\),遍历数组一次,数组的长度为 n ,所以时间复杂度为 \(O(n)\)

  • 空间复杂度\(O(n)\),使用 res 数组存储排序后的结果,其中 n 为原数组 nums 的长度。

每题一图


LC 0977.Squares of a Sorted Array
https://chen-huaneng.github.io/2023/12/07/2023-12-7-2023-12-07-lc-0977/
作者
Abel
发布于
2023年12月7日
更新于
2023年12月7日
许可协议