这个是在回溯法的标签里的。回溯法大致是这样,按照深度优先搜索,在解空间树里往前走,如果不行就回退,然后换一条路。在换路的同时剪去错枝,就是一种蛮力的有剪枝的遍历……于是我先用的回溯:
class Solution {
public:
vector<string> readBinaryWatch(int num) {
vector<string> re;
vector<int> bit(10,1);
if(num==0)
{
re.push_back("0:00");
return re;
}
int deep=0;
int hour=0;
int minu=0;
int flag=0;
while(deep>=0)
{
if(flag==1) //flag=1是回溯的过程,在下面往下搜索的时候,改变deep和flag,flag决定回不回溯,deep是定位的,bit[deep]是标志位。
{
if(bit[deep]==1)
{
if(deep<4)
hour-=pow(2,deep);
else
minu-=pow(2,deep-4);
bit[deep]=0;
num++;
if(deep==9) //最后一个是1还得回
{
flag=1;
continue;
}
else //如果不是最后一个且后面1的位置足够,那么还可以往下走,否则还要回
{
if(9-deep>=num)
{
deep++;
bit[deep]=1;
}
else
{
continue;
}
}
}
else if(bit[deep]==0) //如果回溯的时候这个位置标志为0,那么这个位以下的情况都找遍了,还要往上回
{
bit[deep]=1;
--deep;
continue;
}
flag=0;
}
num--;
if(deep<4)
{
hour+=pow(2,deep);
if(hour>11)
{
flag=1;
continue;
}
else
{
deep++;
}
}
else if(deep<10)
{
minu+=pow(2,deep-4);
if(minu>59)
{
flag=1;
continue;
}
else
{
deep++;
}
}
else
{
deep--;
flag=1;
continue;
}
if(num==0)
{
deep--;
string temp;
stringstream ss;
ss<<hour;
ss>>temp;
temp+=":";
string mi;
ss.clear();
ss<<minu;
ss>>mi;
if(minu<10)
temp+="0";
temp+=mi;
re.push_back(temp);
flag=1;
}
}
return re;
}
};
然而可以不用回溯,直接遍历所有的情况,这种情况是1的位数等于num的就塞进去……很简单…..用到了bitset。bitset<>里的是位数,后面的和别的容器意思差不多,()里是初始化。
class Solution {
public:
vector<string> readBinaryWatch(int num) {
vector<string> rs;
for(int h=0;h<12;h++)
for(int m=0;m<60;m++)
{
if(bitset<10>(h<<6|m).count()==num)
{
rs.push_back(to_string(h)+(m<10?":0":":")+to_string(m));
}
}
return rs;
}
};