出栈序列问题归纳

最近温习数据结构方面的一些知识,遇到了很多关于出栈序列的问题。

  大致就是已知元素的入栈序列,然后求出出栈序列。比如入栈为1,2,3,...n,然后求出可能的出栈序列数目,以及判断是否为正确的出栈序列。

  下面就是我遇到的两个问题:

描述

宁宁考虑的是这样一个问题:一个操作数序列,从1,2,一直到n,栈A的深度大于n。

现在可以进行两种操作:

 

1.将一个数,从操作数序列的头端移动到栈的头端(对应数据结构栈的push操作)

2.将一个数,从栈的头端移动到输出序列的尾端(对应数据结构的pop操作)

 

使用这2个操作,由一个操作数序列就可以得到一系列的输出序列,下面为由1 2 3 到 2 3 1 的过程:

 

操作数:1 2 3

栈:

输出端:

 

操作数:2 3

栈:1(栈底)

输出端:

 

操作数:3

栈:2 1(栈底)

输出端:

 

操作数:3

栈:1(栈底)

输出端:2

 

操作数:

栈:3 1(栈底)

输出端:2

 

操作数:

栈:1(栈底)

输出端:2 3

 

操作数:

栈:

输出端:2 3 1

 

现在对于任意一个N,输入端的数据一定是1,2,3...N

对于任意一个序列,请问是否能根据规则产生这样的序列;

输入

输入第一行包含一个整数 n(n <= 1000),表示数列长度,第二行包含n个数a1,a2,…,an, 表示期望顺序。(a1,a2,…,an) ∈ Permutation{1, 2, …, n}

 

输出

如果可以满足,输出 Yes,否则输出No。

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

这题解题思想就是,位于出栈序列 i 的元素A[i],i位置之后的元素,若存在小于A[i]的元素必须是降序排列,否则错误。 

#include "stdio.h"

int main()
{
	int num;
	int *A;
	int i,j,total;
	int max=0;
	int flag=0;

	int wrong =0;
	int temp,k;
	while(scanf("%d",&num)!=EOF)
	{
		A =(int *)malloc(sizeof(int)*num);
		for(i=0;i<num;i++)
		{
			scanf("%d",&A[i]);
		}
		j=0;
		for(i=0;i<num;i++)
		{
			flag=0;
			wrong=0;
			for(j=i+1;j<num;j++)
			{
				if(A[j]<A[i])
				{
					temp = A[j];
					flag=1;
					break;
				}
			}
			if(flag==1)
			{
				for(k=j+1;k<num;k++)
				{
					if(A[k]<A[i]) /*保证A[i]后的元素,比A[i]小的一定降序排列*/
					{
						if(A[k]<temp)
						{
								temp=A[k];
						}
						else
						{
							wrong=1;
							break;
						}
					
					}
				
				}
			}
			if(wrong==1)
			{
				printf("No\n");
				break;
			}
	
		}
		if(wrong==0)
			printf("Yes\n");
		free(A);
	}
	

	
	return 0;
}


下一个题目 就是求出 可能的出栈序列
描述

宁宁考虑的是这样一个问题:一个操作数序列,从12,一直到n,栈A的深度大于n

现在可以进行两种操作:

 

1.将一个数,从操作数序列的头端移动到栈的头端(对应数据结构栈的push操作)

2.将一个数,从栈的头端移动到输出序列的尾端(对应数据结构的pop操作)

 

使用这2个操作,由一个操作数序列就可以得到一系列的输出序列,下面为由1 2 3 到 2 3 1 的过程:

 

操作数:1 2 3

栈:

输出端:

 

操作数:2 3

栈:1(栈底)

输出端:

 

操作数:3

栈:2 1(栈底)

输出端:

 

操作数:3

栈:1(栈底)

输出端:2

 

操作数:

栈:3 1(栈底)

输出端:2

 

操作数:

栈:1(栈底)

输出端:2 3

 

操作数:

栈:

输出端:2 3 1

 

现在对于任意一个N,输入端的数据一定是1,2,3...N

求出可能出现的输出端数据序列的种数。

 

输入

第一行为一个数字T,表示有T组数据。

每组数据只含一个整数n1n≤9)

输出

对于每组数据,输出可能得到的输出序列的总数目

样例输入
1
3
样例输出
5

这道题的解题思路,就是利用递归,每一个元素只可能进栈出栈一次,所以当所有元素都进过栈后统计该中情况的次数

#include "stdio.h"
int sum;
void dfs(int top,int head,int n)
{
	if(head==n+1)
	{
		sum++;
		return;
	}
	if(top>0)
	{
		dfs(top-1,head,n); /*未出过栈 ,则出栈*/
	}
	if(head<n+1)
	{
		dfs(top+1,head+1,n); /*未入过栈,则入栈*/
	}
}
int main()
{
	int testCase;
	int n;
	scanf("%d",&testCase);
	while(testCase--)
	{
		scanf("%d",&n);
		sum=0;
		dfs(0,1,n);
		printf("%d\n",sum);
	}
	return 0;
}


当然题目变化很多,只要好好把握栈的性质,后进先出。这样就会成为我们解题的利器~
  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值