困难的串

题目描述

如果一个字符串包含两个相邻的重复子串,则称它是“容易的串”,其他串称为“困难的串”。例如, BB、ABCDABCD都是容易的串,而D、DC、ABDAD、CBABCBA都是困难的串。

输入正整数n和L,输出由前L个字符组成的、字典序第n个困难的串。例如,当L=3时,前7个困难的串 分别为A、AB、ABA、ABAC、ABACA、ABACAB、ABACABA。输入保证答案不超过80个字符。

样例输入:

  7  3

30 3

样例输出:

ABACABA

ABACABCACBABCABACABCACBACABA

题目理解

困难的串:串中不含有相邻的相同子串 如ABAC
容易的串:含有相邻且相同的字串 如ABAB
输入L代表要找的串长
输入n代表所用到的前n个字符ABC…
要求 找到长度为L 前n个字典序最小的字符串(大写字母组成)

解体思路

往一个字符串中不断添加字母,要求字典序最小,所以能想到每次添加A,但是有要求无重复字串,所以要添加一个判断,若加入A之后,所构成的串变成了容易的串,就要舍弃加入A,转而加入B,同理一直往后判断,一直找到能构成困难的串的那个字母。
这种寻找的顺序很容以就能想到使用dfs来做。
两个难点

  1. 判断一个串加入某个字母后是否变成了容易的串
  2. dfs这个函数应该怎么写

代码

public class 困难的串 {
	
public static void main(String[] args) {
	dfs("",7,3);
	
}
static int count=0;
public static void dfs(String str,int n,int l) {
	for(char i='A';i<'A'+l;i++) {
		if(isHard(str,i)) {
			str = str+i;
			System.out.print(i);
			count++;
			if(count==n) {
				System.exit(0);
			}
			dfs(str,n,l);
		}
		
	}
}
public static boolean isHard(String prefix,char i) {
	int count = 0;
	for(int j=prefix.length()-1;j>=0;j-=2) {
		String s1 = prefix.substring(j,j+count+1);
		String s2 = prefix.substring(j+count+1)+i;
		if(s1.equals(s2)) {
			return false;
		}
		count++;
	}
	return true;
}
}

代码剖析

public static boolean isHard(String prefix,char i) {
	int count = 0;
	for(int j=prefix.length()-1;j>=0;j-=2) {
		String s1 = prefix.substring(j,j+count+1);
		String s2 = prefix.substring(j+count+1)+i;
		if(s1.equals(s2)) {
			return false;
		}
		count++;
	}
	return true;
}

这个函数用于判断加入字符后是否仍然是困难得到串
指针j首先指向串尾 此后每次向后退两个位置 为什么是退两个而不是退一个哪
假如我们称加入的字符A 为 加入字符
先指到最后一个位置
我们想要比较的是 每次对加入字符添加一个字符 然后和他相邻同等长度他前面那个子串进行比较。
在这里插入图片描述
由于每次给前面的加入字符分配一个字符 自己也要增加一个长度 所以每次往后退两个位置。

int count=0;
for(int j=prefix.length()-1;j>=0;j-=2) {
		String s1 = prefix.substring(j,j+count+1);
		String s2 = prefix.substring(j+count+1)+i;
		if(s1.equals(s2)) {
			return false;
		}

下面仔细看substring函数里面的内容 s1从j指针开始 到j+count+1结束(不包括j+count+1)。这个count在控制每次所比较的子串长度,每次长度加1
s2从j+count+1开始直到最后。这里也能体现为什么j每次减2。


public static void dfs(String str,int n,int l) {
	for(char i='A';i<'A'+l;i++) {
		if(isHard(str,i)) {
			str = str+i;
			System.out.print(i);
			count++;
			if(count==n) {
				System.exit(0);
			}
			dfs(str,n,l);
		}
		else return;
	}
}

这段代码充分体现了dfs的思想.需要注意的是 对字符的操作可以直接加上一个整型数字来运算。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值