求最长的序列,用m个不同元素使得任意n个连续元素在序列中只出现一次

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)+" ");
		 }
	 }
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值