文章目录
1. 题目来源
2. 题目解析
正则表达式匹配相关,?可以匹配任意字符
方法一:分类讨论
- 时间有效位置就 4 位,暴力分情况即可。
- 注意可能会有连续的
?
出现在字符串中,所以需要判断好情况。 - 首个元素最难判断,要填 2 的话,第二个元素必须是 0~3 之间,或者是
?
。 - 一开始忘记分类的完整性,错了很多次…
方法二:暴力模拟
- 按时间从大到小开始匹配,
?
能匹配任意字符,若数字位和枚举的数字位不匹配,则当前时间不合法。 - 找到第一个合法时间,由于是从大到小匹配,故即为答案。
时间复杂度: O ( 24 ∗ 60 ∗ 5 ) O(24*60*5) O(24∗60∗5)
空间复杂度: O ( 1 ) O(1) O(1)
代码:
逻辑匹配,容易出错,需要分好情况…
class Solution {
public:
string maximumTime(string time) {
if (time[0] == '?') {
if (time[1] >= '0' && time[1] <= '3' || time[1] == '?') time[0] = '2';
else time[0] = '1';
}
if (time[1] == '?') {
if (time[0] != '2') time[1] = '9';
else time[1] = '3';
}
if (time[3] == '?') time[3] = '5';
if (time[4] == '?') time[4] = '9';
return time;
}
};
从大到小匹配即可
class Solution {
public:
string maximumTime(string time) {
for (int i = 23; ~i; i -- ) {
for (int j = 59; ~j; j -- ) {
bool flag = false;
if (time[0] != '?' && (time[0] - '0') != i / 10) flag = true;
if (time[1] != '?' && (time[1] - '0') != i % 10) flag = true;
if (time[3] != '?' && (time[3] - '0') != j / 10) flag = true;
if (time[4] != '?' && (time[4] - '0') != j % 10) flag = true;
if (!flag) {
string res;
if (i < 10) res += '0';
res += to_string(i);
res += ":";
if (j < 10) res += '0';
res += to_string(j);
return res;
}
}
}
return "";
}
};
一个简单的写法:注意使用 sprintf
将数字格式化到 str
数组中,并且在力扣输出中,string
类型也是可以直接返回一个 char
数组的。
class Solution {
public:
bool check(char s[], string time) {
for (int i = 0; i < 5; i ++ ) {
if (time[i] != s[i] && time[i] != '?')
return false;
}
return true;
}
string maximumTime(string time) {
for (int i = 23; ~i; i -- ) {
for (int j = 59; ~j; j -- ) {
char s[20];
sprintf(s, "%02d:%02d", i, j);
if (check(s, time))
return s;
}
}
return "";
}
};