回溯与递归
递归:递归算法的实质是把问题分解成规模缩小的同类问题的子问题(分治),然后递归调用方法来表示问题的解。
回溯:按选优条件向前搜索,以达到目标。但当探索到某一步时,发现原先选择并不优或达不到目标,就退回一步重新选择,这种走不通就退回再走的技术为回溯法。通过剪枝可以大幅减少解决问题的计算量。
全排列(1~n)
给出数字n,打印1~n的所有可能排列。
基本思路
设置数组P存储所求排列,hashTable数组作为标记数组,标记数字是否已加入排列。假设当前已经填好了P[1]-P[index-1],正准备填P[index]。于是枚举1-n,如果当前枚举到的数字x不在P[1]~P[index-1]中,那么把它填入P[index],然后处理P的第index+1位(递归)。当index = n + 1时,显然P[1]-P[n]已填好,进入递归边界,进行输出。
这里设n=3,代码如下:
#include <cstdio>
const int maxn = 11;
int n, P[maxn], hashTable[maxn] = {
false};
void generateP(int index){
//处理第index号位
if(index == n + 1){
//已经处理完1~n位
for(int i = 1; i <= n; i++){
printf("%d", P[i]);
}
printf("\n");
return ;
}
for(int x = 1; x <= n; x++){
//试图将x填入P[index]
if(hashTable[x] == false){
//x不在P中
P[index] = x;
hashTable[x] = true;
generateP(index + 1