一道栈的压入弹出题,非栈解法记录
主要记录给自己看的: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();
}
};