✈题目
给你一个按 非递减顺序 排序的整数数组 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]
🚠思路
暴力的解决办法先平方再排序,时间复杂度是O(nlogn),空间复杂度是空O(logn)。
另一个思路:数组中的元素经过平方后,其最大值要么出现在原数组的起始位置,要么出现在末尾位置,因为负数的平方会变得很大,可能超过正数。
所以,为了找到平方后的最大值,我们可以使用双指针方法:i从数组的开头开始,j从数组的末尾开始,然后比较两个指针所指向元素的平方值,将较大的那个放入新数组的末尾,并移动相应的指针。这样,我们就能在新数组的末尾位置依次找到平方后的最大值、次大值等。
如果 A[i] * A[i] < A[j] * A[j] 那么 result[k--] = A[j] * A[j]; 。
如果 A[i] * A[i] >= A[j] * A[j] 那么 result[k--] = A[i] * A[i]; 。
🛰暴力拆解
对一个数组nums进行for循环,将所有元素平方,然后将平方后的数组按升序排序,最后返回这个排序后的数组。
/**
* 将给定数组中的每个元素平方后,对结果进行排序并返回。
*
* @param nums 给定的整数数组
* @returns 排序后的平方数数组
*/
function sortedSquares(nums) {
for (let i = 0; i < nums.length; i++) {
nums[i] *= nums[i];
}
nums.sort((a, b) => a - b);
return nums;
}
const arr = [-4, -1, 0, 3, 10];
console.log(sortedSquares(arr));
或者使用for..of更加简洁
function sortedSquares(nums) {
let arr = [];
for (let num of nums) {
arr.push(num * num);
}
return arr.sort((a, b) => a - b);
}
注意
如果这里的sort()不写参数的话,会默认会将元素转换为字符串并按 Unicode 码点顺序排序,而非按数值大小排,输出结果为
[ 0, 1, 100, 16, 9 ],先比较第一位数字,再比较第二位数字。若需按数值从小到大排序,需传入比较函数
🚀双指针
此时的时间复杂度为O(n) 空间复杂度:O(1),相对于暴力解决的解法O(nlog n)还是提升不少的。
function sortedSquares(nums) {
let i = 0;
let j = nums.length - 1;
let k = nums.length - 1;
let arr = [];
while (i <= j) {
let left = nums[i] * nums[i];
let right = nums[j] * nums[j];
if (left < right) {
arr[k--] = right;
j--;
} else {
arr[k--] = left;
i++;
}
}
return arr;
}
🚁总结
这题要求将给定非递减顺序数组的每个数字平方后,再按非递减顺序排序。一开始我们会想到采用暴力解法先平方后排序,但更优解为使用双指针法,从数组两端向中间遍历,比较平方值后逆序放入新数组,时间复杂度为O(n),空间复杂度为O(1)。
📖参考笔记:代码随想录