递归的小题目

本文探讨了递归算法在解决一系列复杂问题上的应用,包括计算斐波那契数列、网格路径计数、集合子集生成、字符串排列、括号组合及8皇后问题等。通过递归方法,不仅展示了算法的简洁性和效率,还深入解析了每种问题的解决策略。
摘要由CSDN通过智能技术生成

recursion:

一些递归的题目:

1) 计算Fibonacci 第n个数


int generate_nfibo(int position)
{
	if (position < 0)
	{
		cout<<"There is no negative position!!";
		return -1;
	}
	vector<int> fibo(position,0);
	fibo[0] = 1;
	fibo[1] = 1;
	for(int i = 2; i < position; i++)
	{
		fibo[i] = fibo[i-1] + fibo[i-2];
	}
	return fibo[position-1];
}

2)M*N的grid,计算从(0,0)到(M,N)不同路线的数目,这里,只能走两个方向,向右走和向下走:

int getPaths(int M, int N)
{
	if(M < 1 || N < 1)
	{
		cout<<"The width and height of grid must be positive!!!"<<endl;
		return -1;
	}
	vector<vector<int>> Pathnum(M,vector<int>(N,0));
	int i,j;
	for(i = 0; i < M; i++)
		Pathnum[i][0] = 1;
	for(j = 0; j < N; j++)
		Pathnum[0][j] = 1;
	for(i = 1; i < M; i++)
		for(j = 1; j < N; j++)
		{
			Pathnum[i][j] = Pathnum[i-1][j]+Pathnum[i][j-1];
		}
	return Pathnum[M-1][N-1];
}

扩展版本:

当grid中有障碍物时,计算从(0,0)到(M,N)不同路线的数目。

int getPathsobstacle(vector<vector<int>> grid, int M, int N)
{
	if(M < 1 || N < 1)
	{
		cout << "Both the height and width must be positive!!"<<endl;
		return -1;
	}
	vector<vector<int>> Pathnum(M,vector<int>(N,0));
	int i,j;
	bool is_obs = false;
	for(i = 0; i < M; i++)
	{
		if(grid[i][0] == 1)
		{
			is_obs = true;
			break;
		}
	}
	if(!is_obs)
	{
		for(i = 0; i < M; i++)
			Pathnum[i][0] = 1;
	}

	is_obs = false;
	for(i = 0; i < N; i++)
	{
		if(grid[0][i] == 1)
		{
			is_obs = true;
			break;
		}
	}
	if(!is_obs)
	{
		for(i = 0; i < N; i++)
			Pathnum[0][i] = 1;
	}
	
	for(i = 1; i < M; i++)
		for(j = 1; j < N; j++)
		{
			if(grid[i][j] == 1)
				Pathnum[i][j] = 0;
			else
				Pathnum[i][j] = Pathnum[i-1][j]+Pathnum[i][j-1];
		}
	return Pathnum[M-1][N-1];
}


3) 返回一个集合的所有子集


void subset(vector<int> &setelem, int start, vector<int>&path, vector<vector<int>>&result)
{
	if(start == setelem.size())
	{
		result.push_back(path);
		return;
	}

	subset(setelem,start+1,path,result);
	path.push_back(setelem[start]);
	subset(setelem, start+1, path, result);
	path.pop_back();

}

void findallsubset(vector<int> &setelem)
{
	vector<int> path;
	vector<vector<int>> result;
	subset(setelem,0,path, result);
	int i,j;
	for(i = 0; i < result.size();i++)
	{
		cout << "( " ;
		for(j = 0; j < result[i].size();j++)
			cout << result[i][j] << " ";
		cout <<" )" << endl;
	}
}


4)计算一个字符串所有的排列:

void permute(string s, int start, string &path, vector<string> &result)
{
	if(start == s.size())
	{
		result.push_back(path);
		return;
	}
	for(int i = start; i < s.size(); i++)
	{
		swap(s[start],s[i]);
		permute(s,start+1,path+s[start],result);
		swap(s[start],s[i]);
	}
}

void stringpermute(string s)
{
	if(s.size() < 1)
		return;
	string path;
	vector<string> result;
	permute(s,0,path,result);
	cout << "There are total "<<result.size()<<" permutations for string s ( " << s <<" ):"<< endl;
	for(int i = 0; i < result.size(); i++)
		cout<<result[i]<<endl;

}

5)生成n个括号的所有有效组合:

void dfs(int leftnum, int rightnum, int n, string &path, vector<string> &result)
{
	if(leftnum == n && rightnum == n)
	{
		result.push_back(path);
	}
	if(leftnum > n || rightnum > n || rightnum > leftnum)
		return;

	dfs(leftnum+1,rightnum,n,path+'(',result);
	
	if(leftnum > rightnum)
		dfs(leftnum,rightnum+1,n,path+')',result);

}

void generatepare(int n)
{
	string path;
	vector<string> result;
	dfs(0,0,n,path,result);
	cout<< n <<"parentheses's valid combinations:" << endl;
	for(int i = 0; i < result.size(); i++)
		cout<<result[i]<<endl;

}

6) 8皇后问题:


void dfs(int col, int N, vector<int>&path,vector<vector<int>>&result)
{
	if(col == N)
	{
		result.push_back(path);
		return;
	}
	for(int i = 0; i < N; i++)
	{
		bool validsign = true;
		for(int j = 0; j < col; j++)
		{
			if(i == path[j] || col - j == abs(i - path[j]))
				{
					validsign = false;
					break;
				}
		}
		if(validsign)
		{
			path.push_back(i);
			dfs(col+1,N,path,result);
			path.pop_back();
		}
	}
}

void print(vector<vector<int>> V, int N)
{
	vector<vector<string>> result;
	string path= "";
	for(int i = 0; i < N; i++)
		path += '*';

	vector<string> singleboard(N,path);
	for(int i = 0; i < V.size(); i++)
	{
		vector<string> tmpboard;
		string tmp = path;
		for(int j = 0; j < N; j++)
		{
			path[V[i][j]] = 'Q';
			tmpboard.push_back(path);
			path[V[i][j]]='*';
		}
		result.push_back(tmpboard);
	}

	for(int i = 0;  i < result.size(); i++)
	{
		vector<string> tmpboard;
		tmpboard = result[i];
		cout << i+1 <<"th board arrangment:"<<endl;
		cout << "{ "<<endl;
		for(int j = 0; j < tmpboard.size(); j++)
			cout <<"["<< tmpboard[j]<<"]"<<endl;
		cout<<"}"<<endl;
	}
}

void n_queens(int N)
{
	vector<int> path;
	vector<vector<int>> result;
	dfs(0,N,path,result);
	cout<< N << " queens problem: there are total "<<result.size()<<" ways of arrangement!"<<endl;
	print(result,N);
	
}

7) 给定一个特定的数字,要求由25,10,5,1相加组成,求所有的满足要求的组合。

void numberofways(int n)
{
	vector<vector<int>> result;
	vector<int> path(4,0);
	int i,j,k,l;
	int weight[] = {25,10,5,1};
	for(i = 0; i <= n/weight[0]; i++)
		for(j = 0; j <= (n-i*weight[0])/weight[1]; j++)
			for(k = 0; k <= (n - i*weight[0]-j*weight[1])/weight[2]; k++)
			{
				int tmp = n - i*weight[0] - j*weight[1]-k*weight[2];
				if(tmp > 0)
				{
					path[0] = i;
					path[1] = j;
					path[2] = k;
					path[3] = tmp;
					result.push_back(path);
					path = vector<int>(4,0);
				}
			}

	cout << "the result for "<<n<<" is:"<<endl;
	cout <<"(25, 10, 5, 1)"<<endl;

	for(int i = 0; i < result.size(); i++)
	{
		cout << "( ";
		for(int j = 0; j < result[i].size(); j++)
			cout << result[i][j]<<" ";
		cout << " )"<<endl;
	}
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值