RGB三个元素为例:m=3;n=3
【实验要求】
R、G、B三个元素进行排列组成一个最长的序列,要求序列中任意三个连续的位置序列的形式是唯一的,求这个最长的序列。
比如:RRRBRR中所有任意的三个连续位置序列有RRR、RRB、RBR、BRR(序列长6=出现的三个一组共4组+2)每组都只在这个长的序列中出现了一次,满足要求;RRRBRBR中所有任意的三个连续位置序列有RRR、RRB、RBR、BRB、RBR(序列长7=出现的三个一组共5组+2)就存在RBR出现了两次,不符合要求。
如果由R、G、B组成的三个连续元素出现的形式有3*3*3=27种,如果存在一个最长的满足要求的序列,那么这个序列中最多包含了这所有27种形式,序列的最大长度将不超过2+27=29。
【结果】RRRGRRBRGGRGBRBGRBBGGGBGBBBRR
【实验思路】
递归过程:每次想要向ArrayList中添加一个字符R/G/B,判断是否符合任意连续的三个序列不重复出现这一条件,从三个字符中任选一个满足这一条件的字符添加进来(我采用的判断顺序是R-G-B);如果三个字符均不满足条件,那么说明序列不能继续了,也就是上一个添加进来的字符是不合适的,所以去掉上一个字符重新选择满足条件的其他字符进行添加。
递归停止条件:RGB排列任意一组不相同,最多有3*3*3=27可能性,若将这些三个一组的序列放在一个长的序列中,这个最长的序列有29个字符组成。所以,但序列小于29继续递归向ArrayList中添加字符,如果等于29说明已经完成了排序。
【实验代码】
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.Queue;
//很好的思路
public class RGB {
ArrayList<Character> arry = new ArrayList<Character>();
int i = 1;
public RGB() {
arry.add('R');
DFS();
printRGB();
}
public static void main(String[] args) {
RGB rr = new RGB();
}
//默认第一个节点是R
char delchar = 'X';
public void DFS() {
if((ischild(arry, 'R')&&delchar!='R')||(ischild(arry, 'G')&&delchar!='G')
||(ischild(arry, 'B')&&delchar!='B')) {
if(ischild(arry, 'R')&&delchar!='R') {
arry.add('R');
}else if(ischild(arry, 'G')&&delchar!='G') {
arry.add('G');
}else if(ischild(arry, 'B')&&delchar!='B') {
arry.add('B');
}
i = i+1;
delchar = 'X';
}else {
delchar = arry.get(arry.size()-1);
arry.remove(arry.size()-1);
i = i-1;
}
if(i<29) {
DFS();
}
}
//判断c3能不能作为当前节点的一个子节点
public boolean ischild(ArrayList<Character> aList,char c3) {
boolean isc = true;
if(aList.size()>1) {
char c1 = aList.get(aList.size()-2);
char c2 = aList.get(aList.size()-1);
for(int i = 2;i<aList.size();i++) {
if(c3==aList.get(i)&&c2==aList.get(i-1)&&c1==aList.get(i-2)) {
isc = false;
break;
}
}
}
return isc;
}
//打印出来整个序列
public void printRGB() {
System.out.println("序列长度为:"+i);
for(int i = 0;i<arry.size();i++) {
System.out.print(arry.get(i)+" ");
}
}
}