题目描述
警察在侦破一个案件时,得到了线人给出的可能犯罪时间,形如 “HH:MM” 表示的时刻。
根据警察和线人的约定,为了隐蔽,该时间是修改过的,
解密规则为:利用当前出现过的数字,构造下一个距离当前时间最近的时刻,则该时间为可能的犯罪时间。
每个出现数字都可以被无限次使用。
输入描述
形如HH:SS字符串,表示原始输入。
输出描述
形如HH:SS的字符串,表示推理处理的犯罪时间。
备注
1.可以保证现任给定的字符串一定是合法的。
例如,“01:35”和“11:08”是合法的,“1:35”和“11:8”是不合法的。
2.最近的时刻可能在第二天。
用例
输入 | 输出 |
---|---|
20:12 | 20:20 |
23:59 | 22:22 |
12:58 | 15:11 |
18:52 | 18:55 |
23:52 | 23:53 |
09:17 | 09:19 |
07:08 | 08:00 |
package odjava.分100;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.Scanner;
import java.util.regex.Pattern;
/**
* 深度优先算法
* 输入 输出
* 20:12 20:20
* 23:59 22:22
* 12:58 15:11
* 18:52 18:55
* 23:52 23:53
* 09:17 09:19
* 07:08 08:00
*/
public class 解密犯罪时间_68 {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
// 读取输入的小时和分钟
String[] tmp = sc.nextLine().split(":");
String hour = tmp[0]; // 小时
String minute = tmp[1]; // 分钟
// 调用解密方法并打印结果
System.out.println(getResult(hour, minute));
}
public static String getResult(String hour, String minute) {
// 创建 HashSet 用于存储小时和分钟中的不重复数字
HashSet<Character> set = new HashSet<>();
for (int i = 0; i < hour.length(); i++) set.add(hour.charAt(i)); // 将小时中的数字添加到 HashSet 中
for (int i = 0; i < minute.length(); i++) set.add(minute.charAt(i)); // 将分钟中的数字添加到 HashSet 中
Character[] arr = set.toArray(new Character[0]); // 将 HashSet 转换为数组
// 创建 ArrayList 用于存储所有可能的时间组合
ArrayList<String> res = new ArrayList<>();
// 调用深度优先搜索方法,生成所有可能的时间组合
dfs(arr, new LinkedList<>(), res);
// 对生成的时间组合进行排序
res.sort(String::compareTo);
// 查找当前时间的下一个最近时间
int index = res.indexOf(hour + minute);
String recentTime;
if (index == res.size() - 1) {
recentTime = res.get(0); // 如果当前时间是最后一个时间组合,则下一个时间是第一个时间组合
} else {
recentTime = res.get(index + 1); // 否则,下一个时间是当前时间组合的下一个时间组合
}
// 将时间组合拆分为小时和分钟,并返回
String[] split = recentTime.split("");
split[1] += ":"; // 添加冒号分隔符
return String.join("", split); // 将拆分后的小时和分钟组合成字符串并返回
}
// 定义正则表达式,用于匹配有效的时间格式
static Pattern p = Pattern.compile("(([01][0-9])|([2][0-3]))[0-5][0-9]");
// 深度优先搜索方法,生成所有可能的时间组合
public static void dfs(Character[] arr, LinkedList<Character> path, ArrayList<String> res) {
// 如果路径长度为 4,则表示已经生成了一个有效的时间组合
if (path.size() == 4) {
// 将路径转换为字符串
StringBuilder sb = new StringBuilder();
for (Character c : path) sb.append(c);
String timeStr = sb.toString();
// 如果字符串符合有效的时间格式,则将其添加到结果列表中
if (p.matcher(timeStr).find()) {
res.add(timeStr);
}
return;
}
// 遍历数字数组,并逐个添加到路径中,继续搜索
for (Character c : arr) {
path.add(c); // 添加当前数字到路径中
dfs(arr, path, res); // 递归搜索下一个数字
path.removeLast(); // 移除最后一个数字,回溯到上一步
}
}
}