LC-977

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

进阶:

  • 请你设计时间复杂度为 O(n) 的算法解决本问题

Related Topics

  • 数组
  • 双指针
  • 排序

官方的解法是先找到正负分界下标,双指针是从分界往两边,小的值放入结果数组头部。

也可以, 双指针从两边往中间,大的值放入结果数组尾部, 不用事先遍历数组求正负分界下标,不过在俩个指针相遇前都需要对两个指针位置的数组值做平方运行,而官方的解法只要有一端走到头部或者尾部,就不用做平方和比较了,把没走完的一端的值依次放进数组就好,或者直接做数组拷贝,在一些原数组正负值数量差距较大的效率可能会有差异。

    public int[] sortedSquares(int[] nums) {
        // 左指针,指向原数组最左边
        int left = 0;
        // 有指针,指向原数组最右边
        int right = nums.length - 1;
        // 创建一个新数组,存储平方值
        int[] result = new int[nums.length];
        // 得到元素值平方值,从新数组最后位置开始写
        int write = nums.length - 1;
        // 左右指针相遇(逐渐靠拢的过程)之后不再循环
        while (left <= right){
            // 如果原数组的左指针对应的平方值大于右指针,那么往新数组最后位置写入左指针对应的平方值
            if (nums[left] * nums[left] > nums[right] * nums[right]){
                result[write] = nums[left] * nums[left];
                // 左指针右移
                left ++;
                // 移动新数组待写入的位置
                write --;
            }
            else {
                result[write] = nums[right] * nums[right];
                right --;
                write --;
            }
        }
        return result;
    }

posted @ 2022-03-06 19:45  Ricardo_ML  阅读(39)  评论(0编辑  收藏  举报