一道栈的压入弹出面试题,栈和非栈解法记录

博客介绍了两种解决判断栈弹出序列问题的方法:一种是递归解法,通过保证弹出序列中每个数字右边的较小数字必须按照从大到小的顺序排列来判断;另一种是使用vector模拟栈操作,依次压入序列并检查栈顶元素是否与弹出序列匹配。代码示例展示了这两种方法的具体实现。
摘要由CSDN通过智能技术生成

一道栈的压入弹出题,非栈解法记录

主要记录给自己看的:20210322
题目如下:
输入两个整数序列,第一个序列表示栈的压入顺序,请判断第二个序列是否为该栈的弹出顺序。假设压入栈的所有数字均不相等。例如序列 1,2,3,4,5 是某栈的压入顺序,序列 4,5,3,2,1是该压栈序列对应的一个弹出序列,但4,3,5,1,2就不可能是该压栈序列的弹出序列

1.递归解法;2.栈的解法
主要思路:保证所判定的位值,其右边所有小于该值的数必须按照从大到小的相对顺序必须从大到小排列,例如45231中的4,其右边的231排列相对顺序应该是321,比如43521中的321的相对顺序。

#define NUMCOUNT 6
int* iRecord;

int addarray(int a[],bool bDelZero)
{
int itemp = 0;
int i10 = 1;
if(bDelZero)
{
int temp[NUMCOUNT] = {0};
for(int i =0,j=0;i<NUMCOUNT;i++)
if(a[i] == 1)
temp[j++] = i+1;

	for(int i =0;i<NUMCOUNT;i++,i10*=10)
		itemp += temp[i]*i10;
}
else
{
	for(int i =0;i<NUMCOUNT;i++,i10*=10)
		itemp += a[i]*i10;
}
return itemp;

}

void Func(int iObj,int iCount)
{
static int ibegin = iObj;
if(iCount == NUMCOUNT)
ibegin = iObj;

if(iCount == 1)
{
	cout<<ibegin<<" is ok"<<endl;
	for(int i = 0;i < NUMCOUNT ;i++)
		iRecord[i] = 1;
	return;
}
//to get the first num,when enter the func
int i10 = 1;
for(int i = 0;i < iCount-1;i++)
	i10 *= 10;
int iFirst = (iObj / i10);
iRecord[iFirst-1] = 0;
int iRest = iObj - iFirst * i10;

//to record the num which is less than ifirst in the rest
int b[NUMCOUNT] = {0};
for(int i =0;i<NUMCOUNT;i++)
{		
	if(iRecord[i] != 0 && (i < iFirst))
		b[i] = 1;
}

int c[NUMCOUNT] = {0};
int itemptest = iRest;
i10 = 1;		
for(int j=0;j<iCount-2;j++)
	i10 *= 10;
for(int j=iCount-1;j>0;j--)
{
	int itemp = itemptest/i10-1;
	c[j-1] = itemp+1;
	itemptest -= (itemptest/i10*i10);
	i10 /= 10;
}

int d[NUMCOUNT] = {0};
for(int k = 0,j=0;k<NUMCOUNT;k++)
{
	if( c[k]<iFirst )
	{
		d[j++] = c[k];
	}
}

for(int i = iCount - 1;i >= 0;i--)
{
	if(b[i] == 1)
	{
		for(int j = 0;j<NUMCOUNT;j++)
		{
			if(c[j] == (i+1))
			{					
				if(addarray(b,true) == addarray(d,false))
					Func(iRest,iCount-1);
				else
				{
					cout<<ibegin<<" is false"<<endl;
					break;
				}
			}
		}
		break;
	}
}

}

int _tmain(int argc, _TCHAR* argv[])
{
iRecord = new intNUMCOUNT;
for(int i = 0;i < NUMCOUNT;i++)
iRecord[i] = 1;

Func(643251,NUMCOUNT);
Func(435621,NUMCOUNT);
Func(456321,NUMCOUNT);

delete[] iRecord;
iRecord = NULL;
return 0;

}

2.vector模拟栈的解法
这是牛客网@lizo的代码,理解起来更容易一些。

定义一个vector模拟栈的操作,依次将pushV的元素压入栈中,每次压入都判断栈顶元素是否和popV相同,如果相同,则将栈顶元素弹出。直到所有pushV的元素都被压入。
则如果最终栈是空的,说明popV是一个弹出序列,否则不是弹出序列。

//链接:
//https://www.nowcoder.com/questionTerminal/d77d11405cc7470d82554cb392585106
//来源:牛客网

class Solution {
public:
bool IsPopOrder(vector pushV,vector popV) {
if(pushV.size() == 0) return false;
vector stack;
for(int i = 0,j = 0 ;i < pushV.size()😉{
stack.push_back(pushV[i++]);
while(j < popV.size() && stack.back() == popV[j]){
stack.pop_back();
j++;
if(stack.size() == 0)
break;
}
}
return stack.empty();
}
};

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值