401. Binary Watch

问题:

一块二进制数码手表,4位表示 小时 (0~11),6位表示 分钟 (0~59)

亮灯表示 1,不亮灯表示 0。

求给定num个灯亮,所有表示时间的可能性。

Example:
Input: n = 1
Return: ["1:00", "2:00", "4:00", "8:00", "0:01", "0:02", "0:04", "0:08", "0:16", "0:32"]

Note:
The order of output does not matter.
The hour must not contain a leading zero, for example "01:00" is not valid, it should be "1:00".
The minute must be consist of two digits and may contain a leading zero, for example "10:2" is not valid, it should be "10:02".

  

解法:

解法一:Backtracking(回溯算法)

从最低位到高位进行放置亮灯。

  • 当前状态:到目前为止(9~pos上)放好的灯,path。
  • 选择:从当前位置pos到0,可以放置该亮灯的可能性。
  • 退出递归条件:
    •   剩下0个灯: 将解加入res
    •   pos<0

⚠️  注意:由于本题对象为手表,这里需要去掉 小时>11 或者 分钟>59 的结果。

代码参考:

 1 class Time {
 2 public:
 3     bitset<4> hour;
 4     bitset<6> minite;
 5     Time(){
 6         hour.reset();
 7         minite.reset();
 8     }
 9     string getreads() {
10         string time;
11         time = to_string(minite.to_ulong());
12         if(time.length()<2) time = "0"+time;
13         time = to_string(hour.to_ulong()) + ":" + time;
14         return time;
15     }
16     void set(int pos) {
17         if(pos>9) return;
18         if(pos<4) hour.set(pos);
19         else minite.set(pos-4);
20     }
21     void unset(int pos) {
22         if(pos>9) return;
23         if(pos<4) hour.reset(pos);
24         else minite.reset(pos-4);
25     }
26     bool isvalid() {
27         return minite.to_ulong() <= 59 && hour.to_ulong() <= 11;
28     }
29 };
30 
31 class Solution {
32 public:
33     void DFS(vector<string>& res, int num, Time& path, int pos) {
34         if(!path.isvalid()) return;
35         if(num==0) {
36             res.push_back(path.getreads());
37             return;
38         }
39         if(pos < 0) return;
40         for(int i=pos; i>=0; i--) {
41             path.set(i);
42             DFS(res, num-1, path, i-1);
43             path.unset(i);
44         }
45         return;
46     }
47     vector<string> readBinaryWatch(int num) {
48         vector<string> res;
49         Time path;
50         DFS(res, num, path, 9);
51         return res;
52     }
53 };

解法二:直接求解

遍历0:00~11:59所有解,

将符合表示二进制亮灯数==num的解,加入res。

代码参考:

 1 class Solution {
 2 public:
 3     vector<string> readBinaryWatch(int num) {
 4         vector<string> res;
 5         for(int h=0; h<12; h++) {
 6             for(int m=0; m<60; m++) {
 7                 if(bitset<10> (h<<6 | m).count()==num) {
 8                     res.push_back(to_string(h)+":"+ (m<10?"0":"") + to_string(m));
 9                 }
10             }
11         }
12         return res;
13     }
14 };
原文地址:https://www.cnblogs.com/habibah-chang/p/14320951.html