ALGO-18 单词接龙 —— DFS与字符串处理(java)

前言:java

药丸啊药丸啊真的药丸啊,几天时间没作题,昨天作了一道单词接龙题,作了一整个晚上啊,大几个小时。原本想昨天十一点多的时候,也就是好不容易AC了以后就写题解的,但是AC了以后反而身心俱疲,感受本身蒟蒻,心态收到了冲击。数组

今天上完课写完做业后,仍是心有余悸... 再好好地回顾一下,写一篇题解吧。3d





分析:code

这道题的tag是搜索,可是其实还有字符串处理混杂在里面。blog

首先,理解题意就是一个坎,若是不是写到实在思惟混乱了,从新研究了一些样例数据,我可能就一直在错误的理解下挣扎了。仔细去看样例给出的五个单词at touch cheat choose tact, 最终以 a开头的最长的龙是atoucheatactactouchoose。字符串

要注意什么呢,题意要求,在两个单词相连时,其重合部分合为一个部分,也就是说,只有把单词的最小重合部分合并,才能保证最大,而且,要连就要整个单词连上去,不能截取。那么所受到的限制就仅仅是末尾最后一次接上的串了。必定要理清这个思路,不然会绕晕。字符串处理

另一个注意点时,每一个单词最多用两次,那就用int数组去计数,不要用boolean了。string

最后要特别注意的是,题目指出,相邻的部分不能存在包含关系,可是!若是是自身和自身链接,是不属于在包含关系里的,也就是说,容许自身和自身进行链接it

还有其余的一些边边角角的就都写在注释里吧。class


实现:

import java.util.Scanner;

public class Main {

	static int n = 0, result = 0;
	static String[] word; // 记录字符串
	static char first; // 记录开头的字母
	static int visit[]; // 记录单词出现的次数
	static String link; // 记录链接串

	// dfs搜索
	static void dfs(String str) {
		String temp = str;
		if (result <= str.length()) {
			result = str.length();
		}
		for (int i = 0; i < word.length; i++) {
			if (visit[i] < 2 && connect(str, word[i])
					&& check(str, word[i]) == false) {
				visit[i]++;
				dfs(link);
				str = temp; // 必定要回溯!不要改变str!
				visit[i]--;
			}
		}
	}

	// 检查是否为最小重合部分
	static boolean connect(String a, String b) {
		char a1[] = a.toCharArray();
		char b1[] = b.toCharArray();
		for (int i = 0; i < Math.min(a.length(), b.length()); i++) {
			// 若是a1末尾的和a2开头的相等
			if (a1[a1.length - 1] == b1[i]) {
				// 两个串分别往前推着检查
				for (int j = a1.length - 1, k = i; j >= 0 && k >= 0; j--, k--) {
					if (a1[j] != b1[k]) {
						return false;
					}
					// 若是检查直到b1的第一位,都相等,则找到了重合部分
					if (k == 0) {
						b = b.substring(i + 1);// 取出这个重合部分,留下后面的字符串
						link = a + b;// 造成链接串
						return true;
					}
				}
			}
		}
		return false;
	}

	// 检查是否有包含关系
	public static boolean check(String a, String b) {
		// 相同不算在包含的状况下
		if (a.equals(b)) {
			return false;
		}
		// 没有包含关系:
		for (int i = 0; i < Math.min(a.length(), b.length()); i++) {
			if (a.charAt(i) != b.charAt(i)) {
				return false;
			}
		}
		return true;
	}

	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		n = sc.nextInt();
		word = new String[n];
		for (int i = 0; i < n; i++) {
			word[i] = sc.next();
		}
		first = sc.next().charAt(0);
		visit = new int[n];
		sc.close();

		for (int i = 0; i < word.length; i++) {
			if (word[i].charAt(0) == first) {
				dfs(word[i]);
			}
		}
		System.out.println(result);
	}
}