您的位置:首页 > 产品设计 > UI/UE

LeetCode Unique Binary Search Trees

2014-03-04 21:19 423 查看
卡特兰数,这题直接答1/(n+1)C(n,2n)最简单,而且时间也是最快的;但是怎么求出来的呢?下面的一道题是具体怎么构造二叉树,二叉树得不断开辟空间,进栈出栈的折腾还得删除空间(递归时要恢复现场);所以我打算从1,2,3,n的入栈顺序,找出所有可能的出栈顺序,这个结果的个数也就是该题的结果。就是这个程序,没想到自己写了一天也没写出来,下面是我的错误的程序:

void numPushPop(int n,int i,vector<int> &stk,int &num,vector<int> &temp,vector<vector<int> > &ret)//,bool &pushed
{
if(i>n)
{
/*int t;
vector<int>::iterator iter = stk.rbegin();
while(iter!=stk.rend())
{
temp.push_back(*iter);
iter++;
}
ret.push_back(temp);
temp.clear();
num++;*/
return ;
}
if(stk.empty())
{
stk.push_back(i);
i++;
//if(i==n)
//	pushed = true;
numPushPop(n,i,stk,num,temp,ret);
//pushed = false;
i--;
int t = stk[stk.size()-1];
temp.push_back(t);
if(temp.size()==n)
{
ret.push_back(temp);
temp.clear();
num++;
}
stk.pop_back();//recovery stk
}
else
{
int t = stk[stk.size()-1];
temp.push_back(t);
if(temp.size()==n)
{
ret.push_back(temp);
temp.clear();
num++;
}
//i--;
stk.pop_back();
numPushPop(n,i,stk,num,temp,ret);
//temp.pop_back();//recovery temp
stk.push_back(t);//recovery stk
stk.push_back(i);//reset
i++;
//if(i==n)
//	pushed = true;
numPushPop(n,i,stk,num,temp,ret);
i--;//pushed = false;//recovery
t = stk[stk.size()-1];
temp.push_back(t);
if(temp.size()==n)
{
ret.push_back(temp);
temp.clear();
num++;
}
stk.pop_back();//recovery
}
}
上面程序的问题是没法恢复temp,显然temp.clear();破坏了递归。所以失败了。下面是别人的,真是见识了,花了一个小时研究了一下。

void finn(const int n,int cur,vector<int>&stac,vector<int>&outL,int&count,vector<vector<int> > &ret)
{
if((int)outL.size ()==n)//终点
{
//print(outL);
ret.push_back(outL);
count++;
}
if(cur!=n+1)//入栈
{
//操作
stac.push_back(cur);
//进入下层
finn(n,cur+1,stac,outL,count,ret);
//恢复
stac.pop_back ();
}
if(!stac.empty())//出栈
{
//留底
int temp=stac[(int)stac.size ()-1];
//操作
outL.push_back (temp);
stac.pop_back ();
//进入下层
finn(n,cur,stac,outL,count,ret);
//恢复
outL.pop_back ();
stac.push_back (temp);
}
}
思路就是:先入栈,然后恢复后再出栈;不管入栈出栈都进入下一层递归,一旦入栈就一直入到底(cur大于n),一旦都进入了,此时出栈都出来了(因为cur大于n),递归返回上一层时(cur减少),如栈不空继续出栈。说真是说不明白,一行一行调试才能看明白,那还不一定能写出来。简单的代码体现的深厚的递归思想,深厚的程序功底。

注意的是,上面的代码提交通不过,不用输出结果,多了ret没有用,把ret去掉就AC了。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: