递归的优点是直观、易懂:写起来如此,读起来也是这样。但是每次递归都是call stack的不断叠加,对于这个问题,其需要消耗o(n)的栈空间,栈空间,栈空间~~~
于是,我们也可以将其转化成循环的方式来实现
void printallsubsets2(int* a, int n)
{
// initialize flags as false
bool* b = new bool[n];
for(int i = 0; i < n; i++)
{
b[i] = false;
}// use 2 loops教程 to enumerate all possible combinations of (each item's status * number of items),
// in this case: ([true|false] * size of set)
while(true)
{
// get one solution, output it!
for(int i = 0; i < n; i++)
{
if(b[i]) cout << a[i];
}
cout << endl;
// one of the number's status has switched, start over enumeration for that!
// ex: i have following enumeration for 3 numbers:
// 0, 0, 0
// 0, 0, 1
// 0, 1, 0
// 0, 1, 1
// now if i changed the first number's status from 0 to 1, i need to re-enumerate the other 2 numbers
// to get all possible cases:
// 1, 0, 0
// 1, 0, 1
// 1, 1, 0
// 1, 1, 1
int k = n - 1;while(k >= 0)
{
if(b[k] == false) // have we tried all possible status of k?
{
b[k] = true; // status switch, as we only have 2 status here, i use a boolean rather than an array.
break; // break to output the updated status, and further enumeration for this status change, just like a recursion
}
else // we have tried all possible cases for k-th number, now let's consider the previous one
{
b[k] = false; // resume k to its initial status
k--; // let's consider k-1
}
}if(k < 0) break; // all the numbers in the set has been processed, we are done!
}// clean up
delete [] b;
}
有些递归是很容易转化成循环的,用一个循环非常直观的映射过去就是了,如求fibonacci数列; 而有些递归却没有那么直观,甚至可能需要多个循环才能转化过去,这里举个例子:
给出一个集合,如(1, 2, 3, 4),打印出该集合的所有子集
暗影猎手失落的世界 最新版本v30.118.6.0
下载格里姆瓦勒完全版 安卓版v1.2.0
下载忍者武士暗影格斗无限金币版 安卓版v1.82.1
下载忍者必须死34399账号登录版 最新版v1.0.138v2.0.72
下载创造与魔法免登录版 手机版v1.0.0760
创造与魔法是一款高度自由的沙盒冒险手游,该游戏采用了3D最新
创造与魔法gm版 安卓版v1.0.0760
创造与魔法是一款有英雄互娱运营的一款经营沙盒建造手游,该游戏
创造与魔法变态无敌版 v1.0.0760
创造与魔法是一款3DQ版的沙盒模拟建造手游,在这里玩家需要适
腾讯普通话小镇游戏 安卓版v2.2.5
普通话小镇是由腾讯游戏追梦计划推出发行的模拟经营类型普通学习
海岛村 最新版v1.0
海岛村是一款非常好玩的模拟经营类手游,玩家在游戏中将会有一个