有序数组的平方-力扣

题目:

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

看到题觉得很简单,要么将数组内数组平方后排序,或者先将数字的绝对值排序再平方,写出的代码如此。

        //思路,先平方,再排序
        int count=-1;
        for(int i=0;i<nums.size();i++){
            nums[i]=nums[i]*nums[i];
        }//插入排序
        for(int i=1;i<nums.size();i++){
            int key=nums[i];
            int j=i-1;
            while((j>=0)&&nums[j]>key){
                nums[j+1]=nums[j];
                j--;
            }
            nums[j+1]=key;
        }
        return nums;

不过做对了但显示超出时间限制。


 其他博主的代码

第一位

这是官方解答。

  • 直接排序思路:

 

class Solution {
public:
    vector<int> sortedSquares(vector<int>& nums) {
        vector<int> ans;
        for (int num: nums) {//遍历
            ans.push_back(num * num);//插入数字
        }
        sort(ans.begin(), ans.end());//排序
        return ans;
    }
};

 

他的直接排序思路是创建了一个vector数组,然后将平方的数放到另一个数组里面。直接用 sort 排序。

新手 表示没有看懂for循环里面写的什么,所以搜了一下:

nums是一个数组,里面放的是int类型的数据,然后定义了一个int类型的变量num,每循环一次,就从nums数组中取出一个数据来打印。int :表示你要遍历的集合的类型 nums:表示你要遍历的集合的名 num:表示你每遍历集合中一个元素 便存储到该变量。

就说“:”相当于一个in的意思。

  • 双指针

 双指针的思路大致是将负数与正数分成两部分分别平方再合并。

class Solution {
public:
    vector<int> sortedSquares(vector<int>& nums) {
        int n = nums.size();
        int negative = -1;
        for (int i = 0; i < n; ++i) {
            if (nums[i] < 0) {
                negative = i;
            } else {
                break;
            }
        }//以上是计算负数与正数的分割线

        vector<int> ans;
        int i = negative, j = negative + 1;//从j后面开始就是正数
        while (i >= 0 || j < n) {//i代表的是负数数量,n-j是正数数量
            if (i < 0) {//小于0说明只剩下正数,直接记录(正数数量大于负数数量,且负数已全部插入完毕)
                ans.push_back(nums[j] * nums[j]);
                ++j;//正数是从小到大排,所以是j++
            }
            else if (j == n) {//只剩下负数,倒序插入(负数数量大于正数数量,且正数已全部插入)
                ans.push_back(nums[i] * nums[i]);
                --i;//负数是从大到小排,所以是i--
            }
            else if (nums[i] * nums[i] < nums[j] * nums[j]) {//若最小的负数小于最小的正数,先插入负数
                ans.push_back(nums[i] * nums[i]);
                --i;
            }
            else {//否则先插入正数
                ans.push_back(nums[j] * nums[j]);
                ++j;
            }
        }

        return ans;
    }
};

妙啊,几种情况写得明明白白。

  • 方法三

 方法三,其实就是将两个指针从两边往中间靠拢,将大的逆序放入新的指针中。

呜呜呜只能说太厉害了,我完全没想到过。

public:
    vector<int> sortedSquares(vector<int>& nums) {
        int n = nums.size();
        vector<int> ans(n);//这里与前者不一样,这里用到了下标,所以在创建的时候需要用到ans(n)
        for (int i = 0, j = n - 1, pos = n - 1; i <= j;) {//为什么for循环中是这个?前面是几个值得初始化,包括两个指针与现在的位置
            if (nums[i] * nums[i] > nums[j] * nums[j]) {
                ans[pos] = nums[i] * nums[i];
                ++i;
            }
            else {
                ans[pos] = nums[j] * nums[j];
                --j;//j与i的变化原理与前一个做法相同
            }
            --pos;//前一个位置
        }
        return ans;
    }
};

倒着放数字大的,我想了想,那也许也可以正着放小的,不过那样需要找到正负分界线,比这个又麻烦了一点。 

第二位

这位大佬总结了众多排列算法,可以用于复习


好了这道题就到此为止了~

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值