• (PTA乙级)1045 快速排序 (单调栈思想)


    著名的快速排序算法里有一个经典的划分过程:我们通常采用某种方法取一个元素作为主元,通过交换,把比主元小的元素放到它的左边,比主元大的元素放到它的右边。 给定划分后的 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
    
    • 1
    • 2

    输出样例:

    3
    1 4 5
    
    • 1
    • 2
    采用单调栈

    本题的关键就是判断元素X的左边是否存在比X更大的元素,X的右边是否存在比X更小的元素。如果使用嵌套for循环的话可以暴力解决,时间复杂度为O(n2);当然,也可以使用数组max和数组min,分别存储元素X左边的最大值和X右边的最小值,采用动态规划思想解决。

    这里我使用的是单调栈,其实也就是动态规划的思想,使用一个单调递增栈和一个单调递减栈。

    注意,如果没有元素满足情况,在输出0之后还要再输出一个空行

    #include
    #include
    #include
    #include
    #include
    #include
    #include
    using namespace std;
     
    int main(){
    	int n;
    	cin>>n;
    	long long *num=new long long[n+2];
    	int *small=new int [n+2];
    	int *big=new int[n+2];
    	
    	for(int i=0;i<n;i++){
    		cin>>num[i];
    		small[i]=-1;
    		big[i]=-1;
    	}
    	
    	stack<int> s1;
    	// 向右单调递增栈 
    	for(int i=0;i<n;i++){
    		while(!s1.empty()&&num[i]<num[s1.top()]){
    			small[s1.top()]=i;
    			s1.pop();
    		}
    		s1.push(i);
    	}
    	stack<int> s2;
    //	向左单调递减栈 
    	for(int i=n-1;i>=0;i--){
    		while(!s2.empty()&&num[i]>num[s2.top()]){
    			big[s2.top()]=i;
    			s2.pop();
    		}
    		s2.push(i);
    	}
    	 
    	vector<long long> v1;
    	for(int i=0;i<n;i++){
    		if(small[i]<0&&big[i]<0) v1.push_back(num[i]);
    	}
    	cout<<v1.size()<<endl;
    	if(v1.size()>0){
    		sort(v1.begin(),v1.end(),[&](long long a,long long b){
    		return a<b;
    		});
    		cout<<v1[0];
    		for(int i=1;i<v1.size();i++)
    		cout<<" "<<v1[i];
    	}
    	// 如果没有元素了,直接输出一个空行 
    	cout<<endl;
    	return 0;
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
  • 相关阅读:
    狂神说笔记 快速入门Nginx
    【小尘送书-第五期】《巧用ChatGPT快速提高职场晋升力》用ChatGPT快速提升职场能力,全面促进自身职业发展
    PyCharm 手动下载插件
    【计算机毕业设计】旅游网站ssm源码
    计算机毕业设计(附源码)python语言学习系统
    [技术发展-26]:新型信息与通信网络的数据安全
    oracle分区索引的理解和创建思路
    你找到“活着”的意义了吗?
    2022年12月 电子学会青少年软件编程 中小学生Python编程 等级考试一级真题答案解析(选择题)
    数据化运营02 告别迷茫!北极星指标,为业务指明方向
  • 原文地址:https://blog.csdn.net/weixin_45852395/article/details/136713731