参考:http://www.cnblogs.com/MichaelYin/archive/2011/10/10/2206532.html
比如现在又1 2 3 4 5五个数字,规定这五个数字入栈的顺序不变,但是中间可以任意的出栈,出栈的数字就当做输出,请写出程序输出所有的出栈的序列
这个问题可以用很经典的回溯法来解,就是通过递归方法调用,在每一层找出所有可能的操作方式,直到全部输出,另外需要加一句的是在以前我是不知道递归的时候还原现场的,在这个代码里面也是学到了这个知识点,而这个小细节其实是很重要的,当时就是因为这个细节让我在思考递归调用的时候否定了该方法,后来想了许久才重新相通
下面贴出相关代码
public static void SearchStack(Stack<int> input, Stack<int> stack, Stack<int> output)
{
if (input.Count == 0 && stack.Count == 0)
{
//输出结果
Array array = output.ToArray();
foreach (int obj in array)
Console.Write(obj);
Console.WriteLine("");
}
else
{
if (input.Count > 0)
{
//入栈
stack.Push(input.Pop());
SearchStack(input, stack, output);
input.Push(stack.Pop());
}
if (stack.Count > 0)
{
//出栈
output.Push(stack.Pop());
SearchStack(input, stack, output);
stack.Push(output.Pop());
}
}
}
题目:输入两个整数序列。其中一个序列表示栈的push顺序,
判断另一个序列有没有可能是对应的pop顺序。
1、每个已出栈之后的数且小于此数的数都必须按降序排列。复杂度O(n^2),这个要求输入的序列必须是升序的
2.以模拟一个栈,然后通过栈顶得元素和输入序列进行比较,如果没有的,则往前继续入栈,知道找到出栈的那个数字为止,如果中间没有找到,且栈中还有元素,则查找失败
public static bool CheckStack(int[] input, int[] output, int length)
{
int indexOfInput, indexOfOutput;
indexOfInput = 0;
indexOfOutput = 0;
System.Collections.Generic.Stack<int> stack = new Stack<int>();
//初始化
while (input[indexOfInput] != output[0])
{
stack.Push(input[indexOfInput]);
indexOfInput++;
}
//入栈
stack.Push(input[indexOfInput]);
indexOfInput++;
//check
while (indexOfOutput < length)
{
if (stack.Count != 0 && stack.Peek() == output[indexOfOutput])
{
//栈有元素相等,pop
stack.Pop();
indexOfOutput++;
}
else
{
if (indexOfInput < length)
{
//入栈
stack.Push(input[indexOfInput]);
indexOfInput++;
}
else
{
return false;
}
}
}
return true;
}
我的代码更简洁
bool isStack(const char *a,const char *b)
{
if(strlen(a)!=strlen(b))
return false;
if(a==NULL ||b==NULL)
return false;
vector<char> sk(strlen(a));
int psk=0;
while (*b!='\0')
{
if(psk==0 || sk[psk-1]!=*b)
{
if(*a=='\0')
return false;
sk[psk++] = *a++;
}
else
{
--psk;
++b;
}
}
return true;
}
int main()
{
cout<<isStack("12345","43512");
return 0;
}