回溯,题目的本意就是找组合。返回多少种不同的组合。比如说从N个数里面找出K个数不同的组合。
回溯三步骤:
1 画出递归树,找到状态变量。
本题的状态变量有:给定的总数num,组合的初始值start,以及每种不同的组合所对应的时间,这里用pair<int,int> time接收。
因此,递归树可以写成如下:
unordered_map <int> hash{[0,1],[1,2],[2,4],[3,8],[4,1],[5,2],[6,4],[7,8],[8,16],[9,32]};
void Time(int sum, int start, pair<int,int>& time)
2 找到终止点并处理
这里当num = 0 的时候就是终止的时候。
if(num == 0){
if(time->first >11 || time->second > 59){//按照题目要求这类数据应该剪掉,俗称剪枝
return;
}
string hour = to_string(time->first);
string minitue = to_string(time->second);
if(minitue.size() == 1){
minitue.insert(0,'0');
}
res.push_back(hour + ":" + minitue);
return;
}
3 函数主体
for(int i = start ; i < 10 ; i++){
if(time->first >11 || time->second > 59){//按照题目要求这类数据应该剪掉,俗称剪枝
continue;
pair<int,int> temp = time;//回溯时候的上一个状态
if(i < 4){
time->first+= hash[i];
}
else{
time->second+= hash[i];
}
Time(num-1,start+1,time);//当前状态处理完成门进入下一层。
time = temp;//当上面的下一层处理完毕,回溯到没有处理的状态,也就是把time打回处理之前的原形。
}
整体代码如下:
class Solution{
public:
vector<string> res;
unordered_map <int> hash{[0,1],[1,2],[2,4],[3,8],[4,1],[5,2],[6,4],[7,8],[8,16],[9,32]};
void Time(int sum, int start, pair<int,int>& time){
if(num == 0){
if(time->first >11 || time->second > 59){//按照题目要求这类数据应该剪掉,俗称剪枝
return;
}
string hour = to_string(time->first);
string minitue = to_string(time->second);
if(minitue.size() == 1){
minitue.insert(0,'0');
}
res.push_back(hour + ":" + minitue);
return;
}
for(int i = start ; i < 10 ; i++){
if(time->first >11 || time->second > 59){//按照题目要求这类数据应该剪掉,俗称剪枝
continue;
}
pair<int,int> temp = time;//回溯时候的上一个状态
if(i < 4){
time->first+= hash[i];
}
else{
time->second+= hash[i];
}
Time(num-1,start+1,time);//当前状态处理完成门进入下一层。
time = temp;//当上面的下一层处理完毕,回溯到没有处理的状态,也就是把time打回处理之前的原形。
}
vector<string> readBinaryWatch(int num) {
pair<int,int> time;
Time(num,0,time);
return res;
}
};