LeetCode977. 有序数组的平方

977. 有序数组的平方 - 力扣(LeetCode)

Given an integer array nums sorted in non-decreasing order, return an array of the squares of each number sorted in non-decreasing order.

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

//手撕 暴力法
class Solution {
    public int[] sortedSquares(int[] nums) {
        int length = nums.length;
        for(int i = 0;i <length;i++){
            nums[i]=nums[i]*nums[i];
        }
        Arrays.sort(nums);
        return nums;
    }
}

该方法直接对数组的元素进行本地平方,之后使用Arrays的sort方法进行升序排序即可得到答案。

//双指针 归并排序法
class Solution2 {
    public int[] sortedSquares(int[] nums) {
        int length = nums.length;
        int mid = -1;
        //寻找分界点
        for(int i=0; i<length;i++){
            if(nums[i]<0){
                mid=i;
            }else{
                break;
            }
        }
        int[] ans = new int[length];//初始化数组
        int index=0;
        int i=mid;
        int j=mid+1;//刚好能从下标0开始
        while(i>=0||j<length){
            if(i<0){//数组全为正数时 和 负数添加完了
                ans[index]=nums[j]*nums[j];
                j++;
            }else if(j==length){//数组全为负数时 和 正数添加完了
                ans[index]=nums[i]*nums[i];
                i--;
            }else if(nums[i]*nums[i]<nums[j]*nums[j]){//左右两半向外扩散小的先插入
                ans[index]=nums[i]*nums[i];
                i--;
            }else{
                ans[index]=nums[j]*nums[j];
                j++;
            }
            index++;
        }
        return ans;
    }
}

该方法根据数组自身特性将数组划分为左右两半,经过平方后左右两半数组都满足非递减特性,符合归并排序算法的条件,将左右最小的平方数进行比较,较小的插入返回数组下标后移,其中一个数组元素插入完毕则将剩余的数组逐一插入在末尾即可。

// 首尾双指针法
class Solution3 {
    public int[] sortedSquares(int[] nums) {
        int length = nums.length;
        int[] ans = new int[length];
        for(int i=0,j=length-1,pos=length-1;i<=j;){//插入最后一个元素则跳出循环
            if(nums[i]*nums[i]<nums[j]*nums[j]){//将较大的数倒插在返回数组末尾
                ans[pos]=nums[j]*nums[j];
                j--;
            }else{
                ans[pos]=nums[i]*nums[i];
                i++;
            }
            pos--;//循环轮数控制变量
        }
        return ans;
    }
}

该方法相比归并排序减少了对其中一个数组插入完毕的情况,减少了过多的判断,同时将pos设为0开始从头开始插入也是可以的,需要注意的是i和j可能为同一个下标即最后一个元素。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值