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;
}
}