大前端

前端学习之家-大前端

997、有序数组的平方

题目:

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

方法一:暴力解法

import java.util.Arrays;

public class Youxushuzupingfang {
    public int[] sortedSquares(int [] nums){
        for (int i = 0; i <nums.length ; i++) {
            nums[i]*=nums[i];
        }
        //快排
        Arrays.sort(nums);
        return nums;
    }

    public static void main(String[] args) {
        int [] nums = {-7,-3,2,3,11};
        Youxushuzupingfang youxushuzupingfang = new Youxushuzupingfang();
        int [] res =youxushuzupingfang.sortedSquares(nums);
        for (int x:res) {
            System.out.print(x+" ");
        }
    }
}

时间复杂度:O(n+nlogn):其中n是第一个for循环平方产生的,nlogn是快速排序产生的

空间复杂度:O(logn)

输出结果:

4 9 9 49 121 

方法二:双指针法

平方的最大值只可能产生于数组的两端,不可能出现在数组中间,因此可以使用双指针法,分别指向数组的左右两端,比较指针指向的数平方的大小。

public int[] sortedSquares(int [] nums){
        int n = nums.length;
        //创建一个新的数组保存平方后的值
        int [] temp = new int [n];
        //设置左右指针
        for (int i=0,j=n-1,k=n-1; k>=0 ;k--) {
            if(nums[i]*nums[i]>nums[j]*nums[j]){
                temp[k] = nums[i]*nums[i];
                i++;
            }else if(nums[i]*nums[i]<nums[j]*nums[j]){
                temp[k] = nums[j]*nums[j];
                j--;
            }else {//i,j指向的元素平方后的值相等
                temp[k] = nums[i]*nums[i];
            }
        }
        return temp;
    }

    public static void main(String[] args) {
        int [] nums = {-7,-3,2,3,11};
        Youxushuzupingfang youxushuzupingfang = new Youxushuzupingfang();
        int [] res =youxushuzupingfang.sortedSquares(nums);
        for (int x:res) {
            System.out.print(x+" ");
        }
    }

时间复杂度:O(n)

空间复杂度:O(n)

其他版本的双指针解法:对比上面的代码,值得我改进的地方有,使用while循环不需要判断循环次数,左右指针使用left,right表述更加直观

class Solution {
    public int[] sortedSquares(int[] nums) {
        int right = nums.length - 1;
        int left = 0;
        int[] result = new int[nums.length];
        int index = result.length - 1;
        while (left <= right) {
            if (nums[left] * nums[left] > nums[right] * nums[right]) {
                result[index--] = nums[left] * nums[left];
                ++left;
            } else {
                result[index--] = nums[right] * nums[right];
                --right;
            }
        }
        return result;
    }
}

发表评论:

Copyright Your WebSite.Some Rights Reserved.