leetcode-master/problems/0977.有序数组的平方.md

77 lines
2.5 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

## 思路
### 暴力排序
最直观的相反,莫过于:每个数平方之后,排个序,美滋滋,代码如下:
```
class Solution {
public:
vector<int> sortedSquares(vector<int>& A) {
for (int i = 0; i < A.size(); i++) {
A[i] *= A[i];
}
sort(A.begin(), A.end()); // 快速排序
return A;
}
};
```
这个时间复杂度是 O(n + nlogn) 可以说是O(nlogn)的时间复杂度,但为了和下面双指针法算法时间复杂度有鲜明对比,我记为 O(n + nlogn)。
### 双指针法
数组其实是有序的, 只不过负数平方之后可能成为最大数了。
那么数组平方的最大值就在数组的两端,不是最左边就是最右边,不可能是中间。
此时可以考虑双指针法了i指向其实位置j指向终止位置。
定义一个新数组result和A数组一样的大小让k指向result数组终止位置。
如果`A[i] * A[i] < A[j] * A[j]` 那么`result[k--] = A[j] * A[j];` 。
如果`A[i] * A[i] >= A[j] * A[j]` 那么`result[k--] = A[i] * A[i];` 。
如动画所示:
<img src='../video/977.有序数组的平方.gif' width=600> </img></div>
不难写出如下代码:
```
class Solution {
public:
vector<int> sortedSquares(vector<int>& A) {
int k = A.size() - 1;
vector<int> result(A.size(), 0);
for (int i = 0, j = A.size() - 1; i <= j;) { // 注意这里要i <= j因为最后要处理两个元素
if (A[i] * A[i] < A[j] * A[j]) {
result[k--] = A[j] * A[j];
j--;
}
else {
result[k--] = A[i] * A[i];
i++;
}
}
return result;
}
};
```
此时的时间复杂度为O(n)相对于暴力排序的解法O(n + nlogn)还是提升不少的。
效率如下:
<img src='../pics/977.有序数组的平方.png' width=600> </img></div>
**这里还是说一下大家不必太在意leetcode上执行用时打败多少多少用户这个就是一个玩具非常不准确。**
做题的时候自己能分析出来时间复杂度就可以了至于leetcode上执行用时大概看一下就行只要达到最优的时间复杂度就可以了
一样的代码多提交几次可能就击败百分之百了.....
> 更多算法干货文章持续更新可以微信搜索「代码随想录」第一时间围观关注后回复「Java」「C++」 「python」「简历模板」「数据结构与算法」等等就可以获得我多年整理的学习资料。