user-0 提问: 这题求解！ 我感觉需要回溯的算法！但我代码 编不出来！

回复:
user: user-0
content: 懂了，这就是我要的结果，所以说递归其实伴随着回溯！谢谢你的帮助！

user: user-1
content: 引用 2 楼 a____jun 的回复:我根据 你的思路 还是没搞明白是怎么去递归实现问题求解！还有为什么放的数字如果出现过则本次的位置和上次位置的距离必须不小于数字的大小！根据题目意思不应该直接是等于吗？ 代码的话  也还有不解之处！ 你说的对，按照题目的要求应该是直接等于。 之前的代码因为len忘了递增了，所以导致死循环了，修改了一下。试运行了一下能跑出结果。 你自己画个图推导一下就明白了，这个思路很好理解 排了74，接着在1到7中选1个数排，这个数的原则就是不能出现过2次或2次以上，同时和最后一次出现的位置和要排的位置距离要刚好等于这个数 第一次调用，1到7循环，先选1，满足，变成741，递归 》1到7循环，先选1，不满足，继续循环选2，满足，变成7412，递归 -----》1到7循环，先选1，满足，变成74121，递归 ---------》1到7循环，先选1，不满足，继续循环选2，也不满足，再循环选3，满足，变成741213，递归 ------------ 》1到7循环，先选1，不满足，继续循环选2，满足，变成7412132，递归 -----------------》1到7循环，选1选2都不满足（出现2次），继续选3不满足（距离），选4也不满足，选5满足，变成74121325，递归 ---------------------》1到7循环，选1选2不满足，继续选3选4选5都不满足（距离），继续选6满足，变成741213256，递归 -------------------------》1到7循环，选1选2不满足，继续选3选4选5选6都不满足，选7也不满足（距离），循环结束，退出递归 ---------------------》继续上次循环，上次循环到6，所以本次循环选7（相当于回溯），满足，变成741213257，递归 -------------------------》1到7循环，选1选2不满足，继续选3，满足，变成7412132573，递归 -----------------------------》1到7循环，选1选2选3不满足，继续选4选5选6不满足（距离），选7不满足，循环结束，退出递归 -------------------------》继续上次循环，上次到3，本次选4不满足，继续选5选6选7也不满足，循环结束，退出递归 ---------------------》继续上次循环，上次到7，循环结束，退出递归 -----------------》继续上次循环，上次到5，继续选6，满足（相当于回溯），变成74121326，递归 。。。 剩下的LZ自己推导吧，从上的粉红色的数据来看，没退出一层递归，就相当于达到一次回溯（放弃原来的数据，重新选一个），LZ慢慢体会吧  以下是修改过的代码，基本不变，就是修改了上面提到的不对的地方 void find(int a[], int *len) {//为了求一种解才用int*的，如果是求多解，用int就可以了     int tmp = *len; //保存当前位置     for (int i=1, j=0; i<=7; i++) {//1到7中找到适合的数         int cnt=0, idx=0;         for (j=0; j<tmp; j++) {             if(a[j] == i) {//查找数字i出现的次数和位置                 cnt++; //重复出现的次数                 idx = j; //最后一次出现的位置             }         }         if (cnt > 1) continue; //如果出现过2次则跳过数字i         if (cnt>0 && tmp-idx != i+1) continue;//如果最后一次出现的位置间隔不满足则跳过数字i，这里直接用等于         a[tmp] = i; //把当前数字i放入数组         *len = tmp + 1; //之前忘了len增加导致死循环，这里修改一下         if (tmp == 13) {//如果已经到达数组最后的位置             for(int j=0; j<=tmp; j++)                 printf("%d", a[j]);//则打印数组             printf("\n");             return;//结束递归         }         find(a, len); //递归         if (*len == 14) return; //如果要得到多解就把这行注释掉，这行只为了求一种解         *len=tmp; //恢复递归前位置     } }  int main(int argc, const char * argv[]) {     int a[14] = {7, 4};//数组开头     int len = 2;//当前位置     find(a, &len);     if (len != 14)         printf("no solution\n");     return 0; }

user: user-0
content: 我根据 你的思路 还是没搞明白是怎么去递归实现问题求解！还有为什么放的数字如果出现过则本次的位置和上次位置的距离必须不小于数字的大小！根据题目意思不应该直接是等于吗？ 代码的话  也还有不解之处！

user: user-1
content: 回溯也可以，不过递归应该更容易理解一些 思路，数组刚开始保存｛7，4 ｝，然后依次循环用1到7这几个数字放在数组的后面，放的时候要满足2个条件，一，放的数字不能已经使用过2次，二，放的数字如果出现过则本次的位置和上次位置的距离必须不小于数字的大小。如果数组没放满则递归重复上述过程，否则就打印结果并结束递归。 以下是按思路写的代码，没测试过，lz可以参考一下 void fn(int a[], int *len) {//为了求一种解才用int*的，如果是求多解，用int就可以了     int tmp = *len; //保存当前位置     for (int i=1; i<=7; i++) {//1到7中找到适合的数         int cnt=0, idx=0;         for (int j=0; j<tmp; j++) {             if(a[j] == i) {//查找数字i出现的次数和位置                 cnt++; //重复出现的次数                 idx = j; //最后一次出现的位置             }         }         if (cnt > 1) continue; //如果出现过2次则跳过数字i         if (cnt>0 &&tmp-idx<i) continue;//如果最后一次出现的位置间隔不满足则跳过数字i         a[tmp] = i; //把当前数字i放入数组         if (*len == 13) {//如果已经到达数组最后的位置             for(int j=0; j<=*len; j++)                  printf(“%d”, a[j]);//则打印数组             return;//结束递归         }         fn(a, len); //递归         if (*len == 13) return; //如果要得到多解就把这行注释掉，这行只为了求一种解         *len=tmp; //恢复递归前位置     } }  int main() {     int a[14] = {7, 4};//数组开头     int len = 2;//当前位置     fn(a, &len);      return 0; }