Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[LeetCode] 401. Binary Watch #401

Open
grandyang opened this issue May 30, 2019 · 0 comments
Open

[LeetCode] 401. Binary Watch #401

grandyang opened this issue May 30, 2019 · 0 comments

Comments

@grandyang
Copy link
Owner

grandyang commented May 30, 2019

 

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:

  • 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".

 

这道题考察我们二进制表,说实话,博主对二进制表无感,感觉除了装b没啥其他的作用,谁会看个时间还要算半天啊,但是这并不影响我们做题,我们首先来看一种写法很简洁的解法,这种解法利用到了bitset这个类,可以将任意进制数转为二进制,而且又用到了count函数,用来统计1的个数。那么时针从0遍历到11,分针从0遍历到59,然后我们把时针的数组左移6位加上分针的数值,然后统计1的个数,即为亮灯的个数,我们遍历所有的情况,当其等于num的时候,存入结果res中,参见代码如下: 

 

解法一:

class Solution {
public:
    vector<string> readBinaryWatch(int num) {
        vector<string> res;
        for (int h = 0; h < 12; ++h) {
            for (int m = 0; m < 60; ++m) {
                if (bitset<10>((h << 6) + m).count() == num) {
                    res.push_back(to_string(h) + (m < 10 ? ":0" : ":") + to_string(m));
                }
            }
        }
        return res;
    }
};

 

上面的方法之所以那么简洁是因为用了bitset这个类,如果我们不用这个类,那么应该怎么做呢?这个灯亮问题的本质其实就是在n个数字中取出k个,那么就跟之前的那道Combinations一样,我们可以借鉴那道题的解法,那么思路是,如果总共要取num个,我们在小时集合里取i个,算出和,然后在分钟集合里去num-i个求和,如果两个都符合题意,那么加入结果中即可,参见代码如下:

 

解法二:

class Solution {
public:
    vector<string> readBinaryWatch(int num) {
        vector<string> res;
        vector<int> hour{8, 4, 2, 1}, minute{32, 16, 8, 4, 2, 1};
        for (int i = 0; i <= num; ++i) {
            vector<int> hours = generate(hour, i);
            vector<int> minutes = generate(minute, num - i);
            for (int h : hours) {
                if (h > 11) continue;
                for (int m : minutes) {
                    if (m > 59) continue;
                    res.push_back(to_string(h) + (m < 10 ? ":0" : ":") + to_string(m));
                }
            }
        }
        return res;
    }
    vector<int> generate(vector<int>& nums, int cnt) {
        vector<int> res;
        helper(nums, cnt, 0, 0, res);
        return res;
    }
    void helper(vector<int>& nums, int cnt, int pos, int out, vector<int>& res) {
        if (cnt == 0) {
            res.push_back(out);
            return;
        }
        for (int i = pos; i < nums.size(); ++i) {
            helper(nums, cnt - 1, i + 1, out + nums[i], res);
        }
    }
};

 

下面这种方法就比较搞笑了,是博主在没法想出上面两种方法的情况下万般无奈使用的,你个二进制表再叼也就72种情况,全给你列出来,然后采用跟上面那种解法相同的思路,时针集合取k个,分针集合取num-k个,然后存入结果中即可,参见代码如下:

 

解法三:

class Solution {
public:
    vector<string> readBinaryWatch(int num) {
        vector<vector<int>> hours{{0},{1,2,4,8},{3,5,9,6,10},{7,11}};
        vector<vector<int>> minutes{{0},{1,2,4,8,16,32},{3,5,9,17,33,6,10,18,34,12,20,36,24,40,48},{7,11,19,35,13,21,37,25,41,49,14,22,38,26,42,50,28,44,52,56},{15,23,39,27,43,51,29,45,53,57,30,46,54,58},{31,47,55,59}};
        vector<string> res;
        for (int k = 0; k <= num; ++k) {
            int t = num - k;
            if (k > 3 || t > 5) continue;
            for (int i = 0; i < hours[k].size(); ++i) {
                for (int j = 0; j < minutes[t].size(); ++j) {
                    string str = minutes[t][j] < 10 ? "0" + to_string(minutes[t][j]) : to_string(minutes[t][j]);
                    res.push_back(to_string(hours[k][i]) + ":" + str);
                }
            }
        }
        return res;
    }
};

 

参考资料:

https://discuss.leetcode.com/topic/59374/simple-python-java

https://discuss.leetcode.com/topic/59401/straight-forward-6-line-c-solution-no-need-to-explain

https://discuss.leetcode.com/topic/59494/3ms-java-solution-using-backtracking-and-idea-of-permutation-and-combination/2

 

LeetCode All in One 题目讲解汇总(持续更新中...)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant