题目 A1101 Quick Sort

-
题意
输入序列,找到满足pivot性质的数(左边的数都小于它,右边的数都大于它),输出其个数及按从小到大顺序输出具体的数字。 -
思路
暴力会超时,所以我们需要从O(n^2)的时间复杂度往下降。根据给出的性质我们可以发现,在遍历的时候如果我们知道在这个点左边的最大值和右边的最大值就可以判断是否为pivot,所以这个和昨天的思路一样,遍历一遍用leftMax[i]存储到此为止最大的值,然后从后向前遍历过程计算最小值,变扫描变判断,我采用答案存在vector的方式,去输出。
注意:个数为0需要输出空行。 -
Code in C++
#include <cstdio>
#include <vector>
#include <algorithm>
const int MAXN = 100001;
int nums[MAXN];
int leftMax[MAXN] = {-1}; // leftMax[i]: 记录从0-i-1最大的数
int main()
{
int n, result;
std::vector<int> ans;
scanf("%d", &n);
for (int i = 0; i < n; ++i)
{
scanf("%d",&nums[i]);
}
int counter = 0;
leftMax[0] = 0; // 第一个数
for (int i = 1; i < n; ++i)
{
if (nums[i-1] > leftMax[i-1])
leftMax[i] = nums[i-1];
else
leftMax[i] = leftMax[i-1];
}
int rightMin = 1000000001; // 记录从n-1~i+1最大的数
for (int i = n - 1; i >= 0; --i)
{
if (rightMin > nums[i])
{
rightMin = nums[i];
if (nums[i] > leftMax[i])
{
++counter;
ans.push_back(nums[i]);
}
}
}
printf("%d\n",counter);
std::sort(ans.begin(), ans.end());
if (counter > 0)
{
for (int i = 0; i < counter; ++i)
{
if (i >= 1)
printf(" ");
printf("%d", ans[i]);
}
}
printf("\n");
return 0;
}
小结
今天先写了暴力超时了,然后开始思考怎么去降复杂度,从n^2要么降为nlogn要么就是n。但是这里没有什么二分搜索或者需要快排等设置到logn的操作,所以就要从降到n的思路去思考,结合昨天的做法就思考到了这个操作。
本文介绍了一种优化的快速排序算法实现,通过预计算左最大值和右最小值来快速找出满足pivot性质的元素,即左侧所有元素均小于它,右侧所有元素均大于它的数。文章详细解释了如何将时间复杂度从O(n^2)降低至O(n),并附带了完整的C++代码实现。
652

被折叠的 条评论
为什么被折叠?



