全排列问题
题目描述:
把1~N这N个整数按不同的顺序摆放,输出所有可能的结果(按字典序从小到大)
这个搜索大致是这样的流程:
深度搜索按照当前填充排列的顺序往后延伸,先放第一个位置,再放第二个位置,以此类推。因为排列的要求是不能有重复的数字,所以需要使用visit[]数组来表示1到n中的某个数字是否被用过。
当你需要在第m个位置上放数字时,你需要将所有可能放的数字检查一遍,看看他们是否被用过,如果没有就放进这个数字,然后搜索下一个位置。这样可以保证所有的可能都被考虑到,因为所有位置所有可能的数字都被考虑了,并且是保证序列正确的情况下进行的搜索。所以只有填满序列,就一定是一个排列。同样的,因为搜索有一定的顺序。例如从序列的第一位到第n位,从数字1往数字n判断是否能填入,所以搜到的序列也是没有重复的,也同样是一个完整的全排列。
(如果难理解,可以在纸上用笔记录代码运行过程,多推几遍即可)
我的代码:
int n,v[20],hashtable[20] = {0};
void DFS(int index)
{
if (index == n)
{
for (int i = 0 ;i < n ;i++)
{
printf("%d",v[i]);
if (i != n - 1) printf(" ");
else printf("\n");
}
return ;
}
for (int i = 1 ;i <= n ;i++)
{
if (hashtable[i] == 0)
{
v[index] = i;
hashtable[i] = 1;
DFS(index + 1);
hashtable[i] = 0;
}
}
}
组合问题
题目描述:
组合就是从n个元素中抽出r个元素(不分顺序且r < = n),输出所有可能的组合(按字典序从小到大)
我的代码:
vector<int> v;
int n,r,num[10];
void DFS(int cnt,int index)
{
if (cnt == r)
{
for (int i = 0 ;i < v.size() ;i++)
{
printf("%d",v[i]);
if (i < v.size() - 1) printf(" ");
else printf("\n");
}
return ;
}
if (index >= n) return;
v.push_back(num[index]);
DFS(cnt+1,index+1);//选择num[index]
v.pop_back();//把选择的pop出来
DFS(cnt,index+1);//不选择num[index]
}
(参考:大佬哦啦哦啦!)