题干:给你一个长度为 5
的字符串 time
,表示一个电子时钟当前的时间,格式为 "hh:mm"
。最早 可能的时间是 "00:00"
,最晚 可能的时间是 "23:59"
。
在字符串 time
中,被字符 ?
替换掉的数位是 未知的 ,被替换的数字可能是 0
到 9
中的任何一个。请你返回一个整数 answer
,将每一个 ?
都用 0
到 9
中一个数字替换后,可以得到的有效时间的数目。比如"?5:00"输出结果为2。
方法一(朴实无华的思路,分开枚举):
1.审题。需要判断小时和分钟上的问号处符合正确时间的情况。某种程度上来说,两种求法是等价的,唯二的差别在于time之中的位置(小时下标为0和1,分钟下标为3和4)和上限(小时为00~23,分钟为00~59)。
2.由此大致确定需要一个判断小时和分钟可选择的数的函数。
思路为,从00到上限循环,在只有一个问号的情况下,和其中某个数字相等次数加1.
要单独思考有两个问号时的上限+1的情况,以及两个都不是问号时的次数为1的情况。
class Solution {
public:
int countTime(string time) {
int hour_choice=0,minute_hour=0,sum=0;
//单独算小时和分钟的可供选择数目再相乘
hour_choice=caltime(23,time);
minute_hour=caltime(59,time);
sum= hour_choice*minute_hour;
return sum;
}
int caltime(int n,string time)
{
int a=0,b=0,c=-1,d=-1,cal=0;
if(n==23){
a=0;b=1;
}
if(n==59)
{
a=3;b=4;
}
if(time.at(a)!='?'){
c=time.at(a)-'0';
}
if(time.at(b)!='?'){
d=time.at(b)-'0';
}
//循环判断
for(int i=0;i<=n;i++){
//只有一个问号
if(i/10==c||i%10==d){
cal++;
}
if(i/10==c&&i%10==d){
//有0个问号
cal=1;
break;
}
}
//考虑两者都是问号的情况
if(c==-1&&d==-1){
cal=n+1;
}
return cal;
}
};
方法二(回溯):
(官方题解)
class Solution {
public:
bool check(const string &time) {
int hh = stoi(time);
int mm = stoi(time.substr(3));
if (hh < 24 && mm < 60) {
return true;
} else {
return false;
}
}
int countTime(string time) {
int res = 0;
function<void(int)> dfs = [&](int pos) {
if (pos == time.size()) {
if (check(time)) {
res++;
}
return;
}
if (time[pos] == '?') {
for (int i = 0; i <= 9; i++) {
time[pos] = '0' + i;
dfs(pos + 1);
time[pos] = '?';
}
} else {
dfs(pos + 1);
}
};
dfs(0);
return res;
}
};