持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第18天,点击查看活动详情
题目
给你一个按 非递减顺序 排序的整数数组 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] <= 104nums已按 非递减顺序 排序
进阶:
- 请你设计时间复杂度为
O(n)的算法解决本问题
解题
解题一:双指针
思路
- 定义小于零的指针(minstart),从下标 0 开始,向左比较并移动,并且找到最大小于零的位置
- 注意:最大不能超过数组长度
- 定义 maxstart 指针(minstart 后一位)开始
- maxstart 向右,minstart 向左,计算两个数组的平方,比较大小,然后存入 result 数组中
- 以此类推,直到将大于零或小于零的部分完全加入数组
- 将剩余的数字按照平方和的结果插入 result 数组中
代码
class Solution {
public int[] sortedSquares(int[] nums) {
int[] result = new int[nums.length];
if(nums.length==0){
return result;
}
int minstart = 0;
while (minstart< nums.length-1 && nums[minstart+1] < 0) {
minstart++;
}
// temp >= 0
int maxstart = minstart+1;
int index = 0;
while (minstart >= 0 && maxstart < nums.length) {
if (Math.abs(nums[minstart]) <= nums[maxstart]) {
result[index++] = nums[minstart] * nums[minstart--];
} else {
result[index++] = nums[maxstart] * nums[maxstart++];
}
}
while (minstart >= 0) {
result[index++] = nums[minstart] * nums[minstart--];
}
while (maxstart < nums.length) {
result[index++] = nums[maxstart] * nums[maxstart++];
}
return result;
}
}
总结
性能分析
- 执行耗时:1 ms,击败了 100.00% 的 Java 用户
- 内存消耗:42.8 MB,击败了 42.32% 的 Java 用户
解题二:双指针 进阶版
思路
按照解题一的思维,我们可以从最大值开始比较并存放
- minIndex 从 0 开始,maxIndex 从 nums.length 开始,这样是为了数组中存在负数时,大值必定在两端
- 比较 nums[minIndex] 和 nums[maxIndex] 取最大值,放入 result 最后
- minIndex 右移,maxIndex 左移,直到相遇
代码
class Solution {
public int[] sortedSquares(int[] nums) {
int n = nums.length;
int[] ans = new int[n];
int length = nums.length;
int leftIndex = 0;
int rightIndex = length - 1;
int[] result = new int[length];
int index = rightIndex;
while (leftIndex <= rightIndex) {
int minValue = nums[leftIndex] * nums[leftIndex];
int maxValue = nums[rightIndex] * nums[rightIndex];
if (minValue > maxValue) {
// 左端值较大
result[index--] = minValue;
leftIndex++;
} else {
result[index--] = maxValue;
rightIndex--;
}
}
return result;
}
}
总结
性能分析
- 执行耗时:1 ms,击败了 100.00% 的 Java 用户
- 内存消耗:43 MB,击败了 57.23% 的 Java 用户