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