一起玩转 LeetCode 977.有序数组的平方

93 阅读2分钟

977.有序数组的平方

力扣题目链接: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) 的算法解决本问题

1、暴力法

思路

将数组 nums 中的数平方后直接排序。

代码

class Solution {
public:
    vector<int> sortedSquares(vector<int>& nums) {
        for (int i = 0; i < nums.size(); ++i) {
            nums[i] *= nums[i];
        }
        sort(nums.begin(), nums.end());
        return nums;
    }
};

复杂度分析 

  • 时间复杂度:O(nlogn)
  • 空间复杂度:O(1)

2、双指针法

思路

题目中的数组是按照升序排序的,那么数组平方的最大值就在数组的两端,我们可以使用两个指针分别指向数组的起始位置和终止位置。每次比较两个指针对应的数,选择较大的那个逆序放入数组并移动指针。

代码

class Solution {  
public:  
    vector<int> sortedSquares(vector<int>& nums) {  
        int n = nums.size();  
        // 定义两个指针i和j,分别指向输入数组的起始和末尾位置  
        int i = 0;  
        int j = n - 1;  
        // 定义变量k,用于记录新数组的最后一个元素的下标  
        int k = n - 1;  
        // 创建result数组,并将所有元素初始化为0  
        vector<int> result(n, 0);  
  
        // 注意这里要i <= j,当i和j相遇时,还需要处理最后一个元素
        while (i <= j) {  
            int left_square = nums[i] * nums[i];  
            int right_square = nums[j] * nums[j];  
  
            // 如果左边的平方小于右边的平方  
            if (left_square < right_square) {  
                // 将右边的平方放入结果数组的第k个位置,并将k减1  
                result[k--] = right_square;  
                // 将指针j向前移动一位  
                --j;  
            // 否则  
            } else {  
                // 将左边的平方放入结果数组的第k个位置,并将k减1  
                result[k--] = left_square;  
                // 将指针i向后移动一位  
                ++i;  
            }  
        }  
        return result;  
    }  
};

复杂度分析

  • 时间复杂度:O(n)
  • 空间复杂度:O(1)