浙大PAT 1045快速排序,如何优化代码,减少时间复杂度

北风吹冷 2015-09-13 08:20:09
著名的快速排序算法里有一个经典的划分过程:我们通常采用某种方法取一个元素作为主元,通过交换,把比主元小的元素放到它的左边,比主元大的元素放到它的右边。 给定划分后的N个互不相同的正整数的排列,请问有多少个元素可能是划分前选取的主元?

例如给定N = 5, 排列是1、3、2、4、5。则:

1的左边没有元素,右边的元素都比它大,所以它可能是主元;
尽管3的左边元素都比它小,但是它右边的2它小,所以它不能是主元;
尽管2的右边元素都比它大,但其左边的3比它大,所以它不能是主元;
类似原因,4和5都可能是主元。
因此,有3个元素可能是主元。

输入格式:

输入在第1行中给出一个正整数N(<= 105); 第2行是空格分隔的N个不同的正整数,每个数不超过109。

输出格式:

在第1行中输出有可能是主元的元素个数;在第2行中按递增顺序输出这些元素,其间以1个空格分隔,行末不得有多余空格。

输入样例:
5
1 3 2 4 5
输出样例:
3
1 4 5



以下是我的代码

#include<iostream>
#include<fstream>
#include<algorithm>
#include<vector>
using namespace std;

int main()
{
int arr[100000];
unsigned int size = 0;
int arrA[100000];
int count=0;
fstream cin("in.txt");
cin>>size;
for(unsigned int i=0;i<size;i++)
{
cin>>arr[i];
}
int maxFromLeft;
int minFromRight;
int current;

int min=*(min_element(arr,arr+size));
int max=*(max_element(arr,arr+size));
for(unsigned int j=0;j<size;j++)
{
current=arr[j];
/*the first number satifies the demand*/
if(j==0&¤t==min)
{
arrA[count++]=current;
}
/*the last number satifies the demand*/
else if( (j==size-1)&¤t==max)
{
arrA[count++]=current;
}
/*the middle number satifies the demand*/
else
{
maxFromLeft=*(max_element(arr,arr+j) );
minFromRight=*(min_element(arr+j+1,arr+size));
if(maxFromLeft<current&¤t<minFromRight)
arrA[count++]=current;
}/*else*/

}
cout<<count<<endl;
sort(arrA,arrA+count);
for(int i=0;i<count;i++)
{
if(i!=count-1)
cout<<arrA[i]<<" ";
else
cout<<arrA[i];
}
system("pause");
}


编译器总是提示运行超时,请问如何解决
...全文
1345 6 打赏 收藏 转发到动态 举报
写回复
用AI写文章
6 条回复
切换为时间正序
请发表友善的回复…
发表回复
弯曲时空Crape 2017-03-02
  • 打赏
  • 举报
回复
这道题是说,一个数是否符合要求必须满足下面的条件: 1、前面的数都小于自己 2、后面的数都大于自己 所以可以卡一个最大值,一个最小值,一个从前向后遍历,另一个从后向前遍历。然后就能得到哪些是我们需要的,把这些数所在的位置进行标记,最后通过优先队列输出。
yhfnaive 2016-11-20
  • 打赏
  • 举报
回复
我是这样做的 从后往前遍历,如果它是之前最小的,就给他一个标记 从前往后遍历,如果它是之前最大的,又有上面做过的标记,那么他是主元
iSilencer 2015-10-25
  • 打赏
  • 举报
回复
漏了一点~~ 最后主元是要按照从小到大的顺序输出的,所以找出原序列的主元后,要将其排下序,算法复杂度O(mlogm),m为主元的数目~
iSilencer 2015-10-25
  • 打赏
  • 举报
回复
楼上两位的说法是错误的。重新排序后,与原序列比较,位置不变的元素,可能是主元,但也会混入非主元元素,如原序列3 2 1 4 5,排序后,是1 2 3 4 5,通过比较主元为2 4 5,但很明显这是错误的,2不是主元。所以主元一定包含在了排序后位置不变的元素中,但位置不变的元素不一定是主元。 我的ac的算法是,开始假设所有元素都是主元,然后从左至右依次遍历序列,如果右边比相邻的左边元素大,则不做操作。然后看下一个相邻的右边元素,原右边元素则变为左边元素。一旦发现右边比相邻的左边元素小,则把该相邻左边和右边元素都标记为非主元,同时保持左边元素不变,右边元素依次向后遍历,只要比左边元素小就标记为非主元,直到发现比左边元素大的元素,将其作为左边元素。按此规则,直到遍历到序列结束。算法复杂度O(n)。 同理,从右往左再遍历一遍,又可以将很多元素标记为非主元。 综上,两次都没有被标记为非主元的元素,即为主元元素。整个算法的复杂度O(n)。
RiqueZhang 2015-10-08
  • 打赏
  • 举报
回复
快速排序的主元在排序后,其位置是不会变化的。 因此,可以先进行快速排序,再对比原序列,找出同一位置上相等元素即可。 时间复杂度O(N logN)
atalentshow 2015-09-15
  • 打赏
  • 举报
回复
不能给他sort一下,然后比较处于原位的即是主元这种方法吗?

33,010

社区成员

发帖
与我相关
我的任务
社区描述
数据结构与算法相关内容讨论专区
社区管理员
  • 数据结构与算法社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧