小Q的非素数和排序问题题目解析

60 阅读2分钟

这道题涉及两个知识点,递归和回溯。回湖方便处理不同的组合问题。

一般来说,递归就有回溯,只是没有用到,就可以省略这部分。 //一定要分成横纵两个方面思考回溯

void backtracking(参数){ if(终止条件){ 存放结果; return; for(选择:本层集合中元素(树中节点孩子的数量就是集合的大小)){//注意i=0,i=start的区别 处理节点 backtracking(路径,选择列表)://递归注意(i)和(i++)的区别 后面会懂 回溯,撤销处理结果

回溯:每次进入递归之后回溯条件,比如12,3,4进行组合。要得到12,13,14的组合方式,我们先将1放进去然后是2,此时如果不0A溯,记录12,回溯得1,将3放进去得13,同理得14。

递归:在条件未达成之前每次到该结束的地方又进入该函数。上面1的回溯可以得到12,13,14的组合方式,但是要得到剩下的就不仅仅需要回溯还需要递归了,1放进去,递归放2,然后放3,得23,回溯得2放4,递归,放34得到所有组合方式。。要点:设置好结束条件。 总的来说回溯是深度,递归是广度

41c9c903d14753c7319984d40a0d492.jpg 在使用回溯算法的时候,需要多使用剪枝,剔除一些无用的条件,实现回溯的优化!不同题型剪不同的枝。

问题描述

小C对排列很感兴趣,她想知道有多少个长度为n的排列满足任意两个相邻元素之和都不是素数。排列定义为一个长度为n的数组,其中包含从1到n的所有整数,每个数字恰好出现一次。

屏幕截图 2024-11-30 154121.png 这道题递归和回溯都用到了 isPrime是为了判断素数。 backtrack就是回溯算法。功能:使用回溯法生成所有可能的排列,并检查相邻元素的和是否为素数。 如果当前排列的长度等于 n,说明找到了一个符合条件的排列,计数器 count 加一,并返回。遍历从 1 到 n 的所有数字:如果数字 i 没有被使用过(used[i] 为 false),并且当前排列为空或当前排列的最后一个元素与 i 的和不是素数,则将 i 加入排列。 标记 i 为已使用,递归调用 backtrack 继续生成下一个位置的排列。递归返回后,撤销标记并从排列中移除 i,继续尝试下一个数字。