您的位置:首页 > 其它

LeetCode-401. Binary Watch

2018-03-27 19:35 288 查看

Description

A binary watch has 4 LEDs on the top which represent the hours (0-11), and the 6 LEDs on the bottom
represent the minutes (0-59).

Each LED represents a zero or one, with the least significant bit on the right.




For example, the above binary watch reads "3:25".

Given a non-negative integer n which represents the number of LEDs that are currently on, return all
possible times the watch could represent.


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

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


Solution 1(C++)

class Solution {
void backtrack(int num, vector<int> bin, vector<string>& res, int index){
if(num==0){
int hour=0, minute=0, i;
for(i=0; i<4; i++){
hour = hour*2+bin[i];
}
for(i=4; i<10; i++){
minute = minute*2+bin[i];
}
if(hour<12 && minute<60){
string time="";
time.append(to_string(hour)); time.append(":");
if(minute<10) time.append("0"+to_string(minute));
else time.append(to_string(minute));
res.push_back(time);
}
else return;
}
else{
for(int i=index; i<10; i++){
bin[i]=1; num -= 1;
backtrack(num, bin, res, i+1);
bin[i]=0; num += 1;
}
}
}
public:
vector<string> readBinaryWatch(int num) {
vector<string> res;
vector<int> bin(10,0);
backtrack(num, bin, res, 0);
return res;
}
};


Solution 2(C++)

class Solution {
public:
vector<string> readBinaryWatch(int num) {
vector<int> m = {1,2,4,8,16,32};
vector<int> h = {1,2,4,8};
vector<string> res;

for (int i = 0; i <= num; i++) {
vector<int> hour = getTime(i, h);
vector<int> min = getTime(num - i, m);
for (auto h : hour) {
if (h > 11) continue;
for (auto m : min) {
if (m > 59) continue;
res.push_back(to_string(h) + ":" + (m<10? "0":"") + to_string(m));
}
}
}

return res;
}

vector<int> getTime(int digits, vector<int> &value) {
vector<int> res;
helper(res, 0, digits, 0, 0, value);
return res;
}

void helper(vector<int> &res, int start, int digits, int sum, int used, vector<int> &value) {
if (used == digits) {
res.push_back(sum);
return;
}
for (int i = start; i < value.size(); i++) {
helper(res, i+1, digits, sum+value[i], used + 1, value);
}
}
};


算法分析

回溯的问题目前我觉得还是有套路的。相同类型题目Easy难度有:LeetCode-784. Letter Case Permutation。当然可以对比着看。

目前就我自己总结的回溯基本套路,当然有可能只限于Easy难度。

首先说一下什么类型的问题可以考虑使用回溯。目前,在我看来,就是排列组合问题适用于回溯。很简单,Easy的两个题都是排列组合。甚至深度优先搜索,广度优先搜索也是先排列组合出所有情况,然后从中选择适合要求的,比如最短路径、或者本题中不超过上限的。

具体的套路就是,一般单独写一个回溯函数。这样主函数中直接调用回溯函数就可以了。

回溯函数目前都设为无返回值的。所以回溯函数参数一般有要返回的结果。还要有题目的输入。

回溯函数体一般由两部分构成,一部分是回溯到底的结果返回处理部分,一部分是回溯部分。结果返回处理部分一般根据实际情况分析,然后实现具体代码。回溯部分可以简单有三步完成:

第一步:做标记,进行尝试。比如此题中,就是由0变1,num减1,上一题中就是字母大小写变化、

第二步:回溯,更新回溯函数参数,然后进行回溯迭代。

第三步:取消标记。比如此题中,将1变回0,num加1,上一题就是字母变回原来大小写形式。

程序分析

略。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: