C++:Leetcode-977题有序数组的平方

C++:Leetcode-977题有序数组的平方

一种暴力解法,先平方后排序,时间复杂度O(nlogn)
一种双指针法,时间复杂度O(n)
重点熟悉掌握双指针的运用



题目

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


暴力解法

  • 先遍历平方后用sort()排序,方法简单,时间复杂度O(nlogn)
/*
Leetcode-977题
题目:
给你一个按 非递减顺序 排序的整数数组 nums,返回 每个数字的平方 组成的新数组,要求也按 非递减顺序 排序。


思路分析:
1.先平方后,排序
2.先排序后平方,此方法不行,因为元素存在负数,-5的平方是比3平方大的,所以不能先排序

//暴力解法!!!简单题!!
时间复杂度O(n + nlog n),其实等同于O(nlog n)
*/

#include "iostream"
#include "vector"
#include "algorithm"

using namespace std;

//熟悉vector下的自建函数排序
//自建排序,降序
bool mysort(const int a, const int b)
{
    
    
    return a > b;
}

//先平方后排序
class Solution
{
    
    
private:
public:
    vector<int> sortedSquares(vector<int> &nums)
    {
    
    
        for (vector<int>::iterator it = nums.begin(); it != nums.end(); it++)
        {
    
    
            *it = (*it) * (*it);
        }
        //   sort(nums.begin(), nums.end(), mysort);
        sort(nums.begin(), nums.end());
        return nums;
    }
};

//先排序后平方
//会因为元素存在负数而出现排序出错
class Solution2
{
    
    
public:
    vector<int> sortedSquares(vector<int> &nums)
    {
    
    
        sort(nums.begin(), nums.end());

        for (vector<int>::iterator it = nums.begin(); it != nums.end(); it++)
        {
    
    
            *it = (*it) * (*it);
        }

        return nums;
    }
};

int main(int argc, char const *argv[])
{
    
    
    vector<int> nums;
    nums.push_back(-4);
    nums.push_back(-1);
    nums.push_back(0);
    nums.push_back(3);
    nums.push_back(10);
    Solution s1;
    s1.sortedSquares(nums);

    //输出
    for (vector<int>::iterator it = nums.begin(); it != nums.end(); it++)
    {
    
    
        cout << *it << endl;
    }

    vector<int> nums2;
    nums2.push_back(-4);
    nums2.push_back(-1);
    nums2.push_back(0);
    nums2.push_back(3);
    nums2.push_back(10);

    Solution2 s2;
    s2.sortedSquares(nums2);
    cout << "s2先排序后平方" << endl;
    //输出
    for (vector<int>::iterator it2 = nums2.begin(); it2 != nums2.end(); it2++)
    {
    
    
        cout << *it2 << endl;
    }
    return 0;
}

双指针法

  • 输入数组的左右指针不断移动,创建新数组的指针,从尾端还是向头端移动
  • 左右指针平方进行比较,较大的指针移动,较小的指针不移动,然后获取较大值再向左移
  • 不断循环至新数组指针到头
  • 时间复杂度为O(n)
/*
此题暴力解法简单,但此代码采用巧妙双指针,需灵活使用

思路:
1.输入数组的左右指针不断移动,创建新数组的指针,从尾端还是向头端移动
2.左右指针平方进行比较,较大的指针移动,较小的指针不移动,然后获取较大值再向左移
3.不断循环至新数组指针到头

//时间复杂度为O(n)
*/

#include "iostream"
#include "vector"
using namespace std;

class Solution
{
    
    
public:
    vector<int> sortedSquares(vector<int> &nums)
    {
    
    
        vector<int> res(nums.size());
        int newIndex = nums.size() - 1;
        int beginIndex = 0;
        int endIndex = nums.size() - 1;
        while (newIndex >= 0) //注意范围!
        {
    
    
            //尾指针平方大
            //尾指针平方赋值新数组,头指针不动,尾指针左移
            if ((nums[endIndex] * nums[endIndex]) >= (nums[beginIndex] * nums[beginIndex]))
            {
    
    
                res[newIndex] = (nums[endIndex] * nums[endIndex]);
                endIndex--;
            }
            //头指针平方大
            //头指针平方赋值新数组,尾指针不动,头指针左移
            else
            {
    
    
                res[newIndex] = (nums[beginIndex] * nums[beginIndex]);
                beginIndex++;
            }

            //新数组指针左移
            newIndex--;
        }

        return res;
    }
};

int main(int argc, char const *argv[])
{
    
    
    //测试!!!
    vector<int> nums;
    nums.push_back(-7);
    nums.push_back(-3);
    nums.push_back(2);
    nums.push_back(3);
    nums.push_back(10);
    Solution s1;
    vector<int> res = s1.sortedSquares(nums);
    for (vector<int>::iterator it = res.begin(); it != res.end(); it++)
    {
    
    
        cout << *it << endl;
    }

    return 0;
}


总结

此题是简单题,重在熟练运用双指针,知道何时采用双指针效率更高,双指针分别代表什么含义
参考代码随想录
https://www.programmercarl.com/0977.%E6%9C%89%E5%BA%8F%E6%95%B0%E7%BB%84%E7%9A%84%E5%B9%B3%E6%96%B9.html#%E5%8F%8C%E6%8C%87%E9%92%88%E6%B3%95

猜你喜欢

转载自blog.csdn.net/Bellwen/article/details/128115655