给定一个初始为空的栈,和n个操作组成的操作序列,每个操作只可能是出栈或入栈
要求在操作序列的执行过程中不会出现非法操作,即不会再空栈时执行出栈操作,同时保证当操作序列完成是栈恰好为空
求符合条件的序列个数
1<=n<=1000
思路:利用栈层次顺序建一棵二叉树,二叉树的节点的值非1即-1(1表示进栈,-1表示出栈)
如n=4,二叉树如下:(8种可能序列)
1
1 -1
1 -1 1 -1
1 -1 1 -1 1 -1 1 -1
满足的有 * * 两种满足
#include <iostream>
#include <queue>
#include <assert.h>
using namespace std;
//二叉树节点数据结构
struct Node
{
int _data;
Node* _left;
Node* _right;
Node(const int& data)
:_data(data)
, _left(NULL)
, _right(NULL)
{}
};
//全局队列
queue<Node*> q;
Node* GetNode(const int& x)
{
return new Node(x);
}
//先序遍历,递归
Node* PrevOrder(Node* root, const int& half, int& sum, int& valied)
{
if (root == NULL){
if (sum == 0)
++valied;
return NULL;
}
sum += root->_data;
if (sum > half || sum < 0){
//不合法,回退
sum -= root->_data;
return root;
}
else{
Node* ret = PrevOrder(root->_left,half,sum,valied);
if (ret == NULL){
sum -= root->_data;
return root;
}
ret = PrevOrder(root->_right, half, sum, valied);
sum -= root->_data;
return root;
}
}
int main()
{
int n;
while (1){
cin >> n;
if (n < 0 || n > 1000 || n % 2 != 0){
cout << "n invailed,please input again:";
continue;
}
if (n == 0)
return 1;
//利用队列,层次建一棵二叉树
q.push(GetNode(1));
Node* head = q.front();
int half = n / 2;
int tmp=pow(2.0,n-1)-1;//2^(n-1)-1
while (tmp--){
q.push(GetNode(1));
q.front()->_left = q.back();
q.push(GetNode(-1));
q.front()->_right = q.back();
q.pop();
}
while (!q.empty()){
q.pop();
}
//统计合法的进栈出栈序列
int valied = 0;
int sum = 0;
Node* cur = head;
//先序遍历
Node* ret = PrevOrder(head,half,sum,valied);
cout << valied << endl;
//初始化厨师条件,一遍下一次循环使用
valied = 0;
sum = 0;
}
system("pause");
return 0;
}
以上实现使用递归方法,递归的深度很深,可尝试使用非递归实现
《完》
转载于:https://blog.51cto.com/lingdandan/1843521