LeetCode 977 :有序数组的平方 - 双指针

103 阅读1分钟

给你一个按 非递减顺序 排序的整数数组 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]

第一种解法: 这是最直白的一种解法了,就是先乘方再排序

var sortedSquares = function(nums) {
    var n = [];//新数组,用来装新的数
    var len = nums.length;
    for(let i = 0;i<len;i++){
        n[i]=Math.pow(nums[i],2);
    }
    n.sort((a,b)=>a-b);
    return n;
};

高效解法: 这种解法用的是双指针,但是其实不是很容易想到。 首先,我们要知道,原数组是按非递减顺序排列的,也就是说,这些数乘方后,按照原顺序排列大小可能是 / 先下后上,所以这时可以运用双指针来比大小,然后依次将数字以一个从大到小的方式排到new array中作为最后的返回值。

而且双指针的解法直接吊打刚才的写法,因为刚才采用的排序的算法是冒泡排序,时间复杂度很高,这种双指针的排序方法基本是常数时间级别的

var sortedSquares = function(nums) {
    
    var len = nums.length;
    var n = new Array(len-1);//新数组,用来装新的数
    var index = len-1;
    var left = 0;
    var right = len-1;

    while(index>=0){
        if(nums[right]+nums[left]>=0){//right指向的数绝对值大
            n[index]=nums[right]*nums[right];
            right --;
        }else if(nums[right]+nums[left]<0){//left指向的数绝对值大
            n[index]=nums[left]*nums[left];
            left ++;
        }
        index--;
    }
    return n;
};