题目描述
警察在侦破一个案件时,得到了线人给出的可能犯罪时间,形如 HH:MM
表示的时刻。
根据警察和线人的约定,为了隐蔽,该事件是修改过的,解密规则为:
利用当前出现过的数字,构造下一个距离当前事件最近的时刻,则该时间为可能的犯罪的时间。每个数字都可以被无限次使用。
输入描述
形如 HH:SS
字符串,表示原始输入。
输出描述
HH:SS
字符串,表示推理处理的犯罪时间。
备注:
- 可以保证现任给定的字符串一定是合法的,例如,“01:35” 和 “11:08” 是合法的,“1:35"和"11:8” 是不合法的。
- 最近的时刻可能在第二天。
示例1
输入:
20:12
输出:
20:20
示例2
输入:
23:59
输出:
22:22
题解
这个问题可以分为以下几个步骤来解决:
- 记录已经出现的数字: 遍历输入的时间字符串,记录出现过的数字。这里可以使用Set 的集合
exists
,用于标记数字0到9是否出现过。- 计算原始时间: 将输入的时间字符串转换为分钟表示,方便后续的计算。
- 枚举所有时间: 使用两层循环枚举所有可能的小时和分钟,然后计算对应的分钟数,得到当前时间点。
- 判断当前时间点是否符合条件: 判断当前小时和分钟的每一位数字是否都在已经出现过的数字中。如果有任何一个数字未出现,说明这个时间点不符合条件,直接跳过。
- 计算时间间隔: 计算当前时间点与原始时间的时间间隔,注意需要考虑第二天的情况。
- 找到最近的时刻: 通过比较时间间隔找到最近的时刻,更新最近时刻的小时、分钟和时间间隔。
- 格式化输出结果: 最终输出找到的最近时刻。
JavaScript
const rl = require('readline').createInterface({
input: process.stdin,
});
var iter = rl[Symbol.asyncIterator]();
const readline = async () => (await iter.next()).value;
// Author: code5bug
void (async function () {
// 读取输入时间字符串
const [h, m] = (await readline()).split(':').map(Number);
// 使用Set记录已经出现的数字
const exists = new Set([...('' + h + m)].map(Number));
// 初始化变量:小时,分钟,最近的时间间隔(分钟)
let hour = 0,
minute = 0,
minDiff = Infinity;
// 将原始时间转换为分钟数
const originalTotalMinutes = h * 60 + m;
// 枚举所有时间,找到下一个距离当前时间最近的时刻
for (let h = 0; h < 24; h++) {
// 检查小时数字是否都存在于Set中
if (!exists.has(Math.floor(h / 10)) || !exists.has(h % 10)) continue;
for (let m = 0; m < 60; m++) {
const currentTotalMinutes = h * 60 + m;
// 检查分钟数字是否都存在于Set中且不是当前时间
if (!exists.has(Math.floor(m / 10)) || !exists.has(m % 10))
continue;
if (currentTotalMinutes === originalTotalMinutes) continue;
// 计算时间间隔(考虑跨天情况)
let diff;
if (currentTotalMinutes > originalTotalMinutes) {
diff = currentTotalMinutes - originalTotalMinutes;
} else {
diff = 24 * 60 - (originalTotalMinutes - currentTotalMinutes);
}
// 找到更近的时刻
if (diff < minDiff) [hour, minute, minDiff] = [h, m, diff];
}
}
// 输出结果,格式化为两位数
console.log(`${hour.toString().padStart(2, '0')}:${minute.toString().padStart(2, '0')}` );
rl.close();
})();
🙏整理题解不易, 如果有帮助到您,请给点个赞 ❤️ 和收藏 ⭐,让更多的人看到。🙏🙏🙏