JS leetcode 有序数组的平方 题解分析,灵活运用Math.pow与Math.abs方法

壹 ❀ 引

郁闷的周一,晚上来做一道简单的算法题提提神,题目来自leetcode977. 有序数组的平方,题目描述如下:

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

示例 1:

输入:[-4,-1,0,3,10]
输出:[0,1,9,16,100]

示例 2:

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

提示:

1 <= A.length <= 10000
-10000 <= A[i] <= 10000
A 已按非递减顺序排序。

我们来简单分析题目,再来说说如何实现它。

贰 ❀ 引 解题思路

题目要求很简单,给定一个升序排列的数组,让我们求数组中每个元素的平方数,并用这些数字再组成一个升序排列的数组。

根据数字范围,很明显数字可能是负数,但是我们知道即便是负数也满足负负得正,所以不管了,直接使用map求出平方数组,并再次排序:

/**
 * @param {number[]} A
 * @return {number[]}
 */
var sortedSquares = function(A) {
    return A.map(item => item * item).sort((a, b) => a - b);
};

因为map返回一个新数组,所以我们再对数组进行排序即可。

刚提交完毕,突然想起Math对象中有专门求幂的API pow,于是再次修改代码:

/**
 * @param {number[]} A
 * @return {number[]}
 */
var sortedSquares = function(A) {
    // item是你要求幂的数字,第二参数是你希望求几次幂
    return A.map(item => Math.pow(item, 2)).sort((a, b) => a - b);
};

提交发现相比第一次提交快了不少,不知道是不是例子问题

那么还有没有其它解决方案呢,有,使用双指针,思路是这样:

我们用左右两个指针i,j分别指向数组头部和尾部,第一次遍历同时取出第一位与最后一位使用abs求绝对值,进行大小比较。

可能有同学对于abs方法求绝对值比较陌生,直接上例子:

Math.abs(-1);//1
Math.abs(-10);//10
Math.abs(10);//10

通过绝对值,如果左边数字大,自然平方更大,那么使用unshift将平方加入新数组,并让 i 自增;如果右边数字大,使用unshift加入新数组并让 j 自增。这里只管将更大的数字unshift依次加入数组即可,只是自增的指针不同。

我们直接上代码:

/**
 * @param {number[]} A
 * @return {number[]}
 */
var sortedSquares = function (A) {
    var i = 0, //左指针
        j = A.length - 1, //右指针
        A_ = []; //新数组
    while (i <= j) {
        // 始终将更大的数加入新数组
        if (Math.abs(A[i]) > Math.abs(A[j])) {
            A_.unshift(Math.pow(A[i], 2));
            i++;
        } else {
            A_.unshift(Math.pow(A[j], 2));
            j--;
        }
    };
    return A_;
};

当然,相比我们最初的实现使用了更多地API,实际上更麻烦了,不过这里也只是提供一种解题思路。

那么到这里本题结束。

原文地址:https://www.cnblogs.com/echolun/p/13069673.html