给定序列,求这个序列的出栈次序

比如1,2,3 的出栈次序可以是{1,2,3}{2,1,3}{2,3,1}{1,3,2}{3,2,1}5种。

其实这个 和leetcode生成括号那个题目很像。题目链接https://leetcode.com/problems/generate-parentheses/

题解

http://www.cnblogs.com/pk28/p/5355711.html

Given n pairs of parentheses, write a function to generate all combinations of well-formed parentheses.

For example, given n = 3, a solution set is:

"((()))", "(()())", "(())()", "()(())", "()()()"

代码中x表示左括号的数量,y表示右括号的数量。

复制代码
class Solution {
public:
    void dfs(int n,string s,int x,int y,vector<string>&v){
        if(y==n){
            v.push_back(s);
            return ;
        }
        if(x<n)dfs(n,s+'(',x+1,y,v);
        if(x>y)dfs(n,s+')',x,y+1,v);
    }
    vector<string> generateParenthesis(int n) {
        vector<string>v;
        string s="";
        dfs(n,s,0,0,v);
        return v;
    }
};
复制代码

 

对于 出栈序列的问题,可以这么理解,对于1、2、3的序列,进栈可以用(表示  出栈可以用) 表示。

那么一个 出栈序列 3 2 1 可以表示为((( )))  、  出栈序列1 2 3 可以表示成()()()。不一一列举了...

把上面的代码 改一改就得到了 出栈序列的写法

/* ***********************************************
Author        :guanjun
Created Time  :2016/8/20 11:22:04
File Name     :a.cpp
************************************************ */
#include <bits/stdc++.h>
using namespace std;
vector<int>v;
vector<int>a;
vector<int>b;
int n,cnt;
void dfs(int x,int y){//进栈次数  出栈次数
    if(y==n){
        for(int i=0;i<b.size();i++)
            cout<<b[i]<<" ";
        for(int i=a.size()-1;i>=0;i--)
            cout<<a[i]<<" ";
        cout<<endl;
        cnt++;
        return ;
    }
    if(x<n){//进栈
        a.push_back(v[x]);
        dfs(x+1,y);
        a.pop_back();
    }
    if(x>y){
        b.push_back(a.back());
        a.pop_back();
        dfs(x,y+1);
        a.push_back(b[b.size()-1]);
        b.pop_back();
    }
}
int main()
{
    cin>>n;
    for(int i=1;i<=n;i++){
        int x;
        cin>>x;
        v.push_back(x);
    }
    cnt=0;
    dfs(0,0);
    cout<<"all kind "<<cnt<<endl;
    return 0;
}

关于出栈序列的总数..其实这是卡特兰数问题。

答案是C(2n,n)-C(2n,n-1);

 

posted on 2016-08-20 15:00  Beserious  阅读(634)  评论(0编辑  收藏  举报