算法之——四处碰壁回溯法01入门案例
文章目录
素数环问题
问题描述:
将数据1~n放入含有n个节点的环,保证任意相邻的两个数的和为素数。
算法基本思路还是比较简单的,首先将第一个数放到保存数据的数组的0索引处,
接着开始放索引1的值一直放到n-1处,但是在这个过程中:
①注意放的时候是否会有重复
②放的时候是否满足和为素数的条件
如果上面条件都满足了就进入下一个位置填写,如果不满足就回退,直到全部填完为止。
代码实现:
import org.junit.Test;
/**
* @author jackTan
*/
public class MainTest {
@Test
public void Test() {
int[] circle = primeCircle(20);
for (int i : circle) {
System.out.print(i+" ");
}
}
public int[] primeCircle(int n) {
//这里其实相当于已经初始化了a[i]=0
int []a = new int[n];
//第一步把a[0]赋值1,指针k指向1
a[0]=1;
int k =1;
//这里我设定k=0时为递归出口
while(k!=0) {
while(a[k]<=n){
a[k]=a[k]+1;
if(Check(a,k)){
break;
}
}
//如果a[k]=n+1说明要回退,如果a<=n说明继续下一步
if(a[k]!=n+1){
if(k==n-1){
k=0;
}else{
k++;
}
}else{
a[k--]=0;
}
}
return a;
}
//判断是否满足要求
boolean Check(int []a,int k) {
//判断想加是否为素数
if(!isPrime(a[k]+a[k-1])){
return false;
}
//判断是否重复
for(int i=0;i<k;i++)
{
if(a[k]==a[i]){
return false;
}
}
//判断首尾是否满足要求
if(k==a.length-1){
if(!isPrime(a[k]+a[0])){
return false;
}
}
return true;
}
//判断是不是素数
boolean isPrime(int n){
for(int i=2;i<n;i++){
if(n%i==0){
return false;
}
}
return true;
}
}
输出结果:
1 2 3 4 7 6 5 8 9 10 13 16 15 14 17 20 11 12 19 18