【最长的密码】
小王在进行游戏大闯关,有一个关卡需要输入一个密码才能通过,密码获得的条件如下:
在一个密码本中,每一页都有一个由26个小写字母组成的若干位密码,每一页的密码不同,需要从这个密码本中寻找这样一个最长的密码,从它的末尾开始依次去掉一位得到的新密码也在密码本中存在。
请输出符合要求的密码,如果有多个符合要求的密码,则返回字典序最大的密码。若没有符合要求的密码,则返回空字符串。
输入描述
密码本由一个字符串数组只组成,不同元素之间使用空格隔开,每一个元素代表密码本每一页的密码
输出描述
个字符串
import java.util.*;
/**
* 该算法的主要思路是先取密码本按照典范从大到小程序,然后遍历每一个密码,不要断其末尾并判断新密码是否在密码本中存在,
* 直接找到符合要求的密码或当前密码被截图只是一个角色。对于子问题则通过递归来解决。
* 如果整个循环结束没有找到符合条件的密码,则返回空字符串。
*/
public class OdAb17 {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
String[] arr = sc.nextLine().split(" "); // 获取输入的密码本,存储在字符串数组中
System.out.println(getResult(arr)); // 输出结果
}
public static String getResult(String[] arr) {
Arrays.sort(arr, (s1, s2) -> { // 按照字典序从大到小进行排序
if (s1.length() != s2.length()) { // 长度不同则直接比较长度,从长到短排列
return Integer.compare(s2.length(), s1.length());
} else { // 长度相同则比较字典序
return s2.compareTo(s1);
}
});
Set<String> setA = new HashSet<>(Arrays.asList(arr)); // 将排序后的密码本转化为哈希集合,方便查找
for (String s : arr) { // 遍历每一个密码
String temp = s;
while (temp.length() > 0) { // 不断截取当前密码的末尾,并判断新的密码是否在密码本中存在
temp = temp.substring(0, temp.length() - 1);
if (setA.contains(temp)) {
if (temp.length() == 1 || getResult(new String[]{temp}) != "") { // 如果新密码只有一位或者新密码的子问题有解,则返回当前密码
return s;
}
}
}
}
return ""; // 没有符合要求的密码,返回空字符串
}
}