⭐算法入门⭐《双指针》简单01 —— LeetCode 977. 有序数组的平方

饭不食,水不饮,题必须刷

C语言免费动漫教程,和我一起打卡!
光天化日学C语言

LeetCode 太难?先看简单题!
C语言入门100例

数据结构难?不存在的!
画解数据结构

闭关刷 LeetCode,剑指大厂Offer!
LeetCode 刷题指引

LeetCode 太简单?算法学起来!
夜深人静写算法

文章目录

  • 一、题目
    • 1、题目描述
    • 2、基础框架
    • 3、原题链接
  • 二、解题报告
    • 1、思路分析
    • 2、时间复杂度
    • 3、代码详解
  • 三、本题小知识

一、题目

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类型的数据;
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) 左右元素都在,需要选择小的那个先进结果数组,然后向外扩展指针;

三、本题小知识

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


你可能感兴趣的:(《LeetCode算法全集》,LeetCode,算法,算法入门,双指针)