题目
给你一个按 非递减顺序 排序的整数数组 nums,返回 每个数字的平方 组成的新数组,要求也按 非递减顺序 排序。(leetcode 977)
示例 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]
解题方法
在刚看到题目的时候,我脑海中第一想法就是暴力破解,但是我也很清楚一定有时间复杂度低一点的办法。以下代码皆是用java写的,不过没什么区别,思路是一样的。
1.暴力破解
暴力破解思路很简单,就是直接将数组每个元素取平方,然后根据平方后的值进行排序。
代码如下:
class Solution {
public int[] sortedSquares(int[] nums) {
int temp = 0;
for(int i=0;i<nums.length;i++){
nums[i] = nums[i]*nums[i];
}
for(int i=nums.length;i>0;i--){
for(int j=0;j<i-1;j++){
if(nums[j]>nums[j+1]){
temp = nums[j];
nums[j] = nums[j+1];
nums[j+1] = temp;
}
}
}
return nums;
}
}
这里的算法的时间复杂度取决于所使用的排序算法的时间复杂度。我这里用的是冒泡排序,所以就是O(n^2)。
2.双指针
因为题目上说的是一个非递减的数组,所以它的平方值最大的元素是在这个数组最左边或者最右边,也就是说我没要查找的顺序应该是从两边到中间。所以很自然就会想到双指针,定义两个指针,让它们从两边向中间靠拢,并且依次比较绝对值(绝对值大的平方一定大),然后将元素平方后依次填入新数组,这里要注意,因为是从大到小的找,所以最先放入新数组的元素是在新数组的后面的位置。
代码如下:
class Solution {
public int[] sortedSquares(int[] nums) {
int[] nums2 = new int[nums.length];
int left = 0;
int right = nums.length-1;
int l = nums.length-1;
while(left != right){
nums2[l--] = (Math.abs(nums[right])>Math.abs(nums[left]))?
(int)Math.pow(nums[right--],2):(int)Math.pow(nums[left++],2);
}
nums2[l] = (int)Math.pow(nums[left],2);
return nums2;
}
}
while循环里用到了一个有点长的三元表达式。
总结
多想多写多练