算法专题(02)双指针(01) 简单LeetCode 977

Posted 英雄哪里出来

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了算法专题(02)双指针(01) 简单LeetCode 977相关的知识,希望对你有一定的参考价值。


一、题目

1、题目描述

  给定一个按 非递减顺序 排序的整数数组 nums,返回 每个数字的平方 组成的新数组,要求也按 非递减顺序 排序。
  样例: n u m s = [ − 4 , − 1 , 0 , 3 , 9 ] nums = [-4,-1,0,3,9] nums=[4,1,0,3,9],输出 [ 0 , 1 , 9 , 16 , 81 ] [0,1,9,16,81] [0,1,9,16,81]

2、基础框架

  • c++ 版本给出的基础框架代码如下,要求返回一个 vector<int>类型的数据;
class Solution {
public:
    vector<int> sortedSquares(vector<int>& nums) {
    }
};

3、原题链接

LeetCode 977. 有序数组的平方

二、解题报告

1、思路分析

  • 首先,如果所有的数都是非负整数,那么直接按照原顺序,对数字平方塞入新的数组就是答案了。
  • 否则,需要找到负数中,下标最大的,令它为 i i i,然后定义令一个指针 j = i + 1 j = i + 1 j=i+1。不断比较 i i i j j j 对应的数的平方的大小关系,然后选择小的那个塞入新的数组,并且更新指针的位置。直到两个指针都到数组边缘时,运算完毕。

2、时间复杂度

  • 两个指针只会往一个方向遍历,最多遍历一次,所以时间复杂度为 O ( n ) O(n) O(n)

3、代码详解

class Solution {
public:
    vector<int> sortedSquares(vector<int>& nums) {
        vector <int> ans;                             // (1)
        if (nums.size() == 0) {                       // (2)
            return ans;
        }
        else if(nums[0] >= 0) {
            for(int i = 0; i < nums.size(); ++i) {    // (3)
                ans.push_back(nums[i] * nums[i]);
            }
        }
        else {
            int i, j;
            for(int p = nums.size()-1; p >= 0; --p) {
                if(nums[p] < 0) {
                    i = p;
                    break;                            // (4)
                }
            }
            j = i + 1;                                // (5)

            while(i >= 0 || j < nums.size()) {        // (6)
                if(i < 0) {                           // (7)
                    ans.push_back(nums[j] * nums[j]);
                    ++j;
                }else if(j >= nums.size()) {          // (8)
                    ans.push_back(nums[i] * nums[i]);
                    --i;
                }else {
                    int i2 = nums[i] * nums[i];
                    int j2 = nums[j] * nums[j];

                    if(i2 < j2) {                     // (9)
                        ans.push_back(i2);
                        --i;
                    }else {
                        ans.push_back(j2);
                        ++j;
                    }
                }
            }
        }
        return ans;

    }
};
  • ( 1 ) (1) (1) ans为结果数组,用来存储最终答案;
  • ( 2 ) (2) (2) 如果给定数组长度为 0,则直接返回空数组;
  • ( 3 ) (3) (3) 给定数组所有元素都为非负整数时,直接有序的生成新的数组,数组元素为原数组元素的平方;
  • ( 4 ) (4) (4) 找到负数中,下标最大的数,记为 i i i
  • ( 5 ) (5) (5) 初始化指针 j = i + 1 j = i + 1 j=i+1
  • ( 6 ) (6) (6) 开始对两个指针进行迭代枚举,结束条件是两个指针都碰到数组的边界;
  • ( 7 ) (7) (7) 左指针退化,左边元素耗尽了;
  • ( 8 ) (8) (8) 右指针退化,右边元素耗尽了;
  • ( 9 ) (9) (9) 左右元素都在,需要选择小的那个先进结果数组,然后向外扩展指针;

三、本题小知识

输入参数为数组时,如果要判断数组第一个元素的状态,记得对数组进行判空;


以上是关于算法专题(02)双指针(01) 简单LeetCode 977的主要内容,如果未能解决你的问题,请参考以下文章

LeetCode日记——算法双指针专题

算法专题(01)二分查找(02) 简单LeetCode 35

算法小讲堂之你真的会双指针吗?

算法入门双指针(中等 - 第二题)LeetCode 567

算法入门双指针(中等 - 第一题)LeetCode 3

⭐算法入门⭐《双指针》困难01 —— LeetCode 76. 最小覆盖子串