LeetCode Unique Binary Search Trees

本文探讨了卡特兰数的概念及其在二叉树构造中的应用,并通过具体的程序实现来寻找所有可能的出栈顺序,展示了两种不同的递归实现方法。

卡特兰数,这题直接答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了。



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值