题目地址:https://leetcode.com/problems/binary-watch/
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”.
题目的说给了这么一个作死的二进制表,不能直接了当地告你时间是多少,要想知道具体时间,你还得做个简单的加法。
上面一排灯,1,2,4,8四个数字表示hour,下面一排灯1,2,4,8,16,32六个数字,表示minute。
其实说来到去就是个组合问题,但是注意了,这里的组合不是边界对齐的组合,这一点会在下面的代码实现中涉及到。
hour范围[0, 1, 2, ……,10, 11]
minute范围[0, 1, 2, 3, ……, 57, 58, 59]
如果是这样的话,那肯定这些灯不能全亮,如果全亮的话,那一天(或者半天)就是15小时63分。所以要注意边界。
如果算一下很快就能得出,上面的灯最多亮3个,下排灯最多亮5个,多了的话必然是外星时间。
那既然这样,也就是说总共也只能是8个灯亮着,加上全灭那一瞬间(0:00),其实也就是9中情况。全灭特殊,直接拿出来当特例就行,剩下的只有8种情况,而且这八种情况也是可罗列出来的。
如果手动都罗列出来了,那一个switch语句就搞定了,而且效率也特高,可以说瞬间毫秒杀。
当然你也可以算一部分,比如,算一下上面灯亮1个有几种情况,2个有几种情况,3个有几种情况。同样下面灯亮1个有几种情况,2个呢,3个呢,……,8个呢?其实我就是这么干的。
剩下的工作无非就是字符转拼接了,简单的很。
因为这个题目的特殊性,正好可以用到Java中的锯齿矩阵,然后利用下标,直接拼接即可。代码实现如下:
public class BinaryWatch {
public List<String> readBinaryWatch(int num) {
List<String> res = new ArrayList<String>();
if (num == 0) {
res.add("0:00");
return res;
}
if (num > 8)
return res;
// 上面一排灯亮的组合情况
String[] top0 = {"0"};
String[] top1 = {"1", "2", "4", "8"};
String[] top2 = {"3", "5", "6", "9", "10"};
String[] top3 = {"7", "11"};
// 下面一排灯亮的组合情况
String[] bottom0 = {"00"}; // length=1
String[] bottom1 = {"01", "02", "04", "08", "16", "32"}; // length=6
String[] bottom2 = {"03", "05", "06", "09", "10", "12", "17", "18", "20", "24", "33", "34", "36", "40", "48"}; // length=15
String[] bottom3 = {"07", "11", "13", "14", "19", "21", "22", "25", "26", "28", "35", "37", "38", "41", "42", "44", "49", "50", "52", "56"}; //length=20
String[] bottom4 = {"15", "23", "27", "29", "30", "39", "43", "45", "46", "51", "53", "54", "57", "58"}; // length=14
String[] bottom5 = {"31", "47", "55", "59"}; // length=4
String[][] top = {top0, top1, top2, top3};
String[][] bottom = {bottom0, bottom1, bottom2, bottom3, bottom4, bottom5};
for (int k= 0; k <= num; k++) {
// 注意这里就是上面所提到的边界不对齐,上下灯的组合情况不一样,所以要加一个边界判断。
if (k > 3 || num - k > 5)
continue;
for (int i = 0; i< top[k].length; i++) {
for (int j = 0; j < bottom[num - k].length; j++) {
res.add(top[k][i] + ":" + bottom[num - k][j]);
}
}
}
return res;
}
public static void main(String[] args) {
BinaryWatch watch = new BinaryWatch();
System.out.println(watch.readBinaryWatch(7));
}
}
我偷懒了,如果全部都列出来的话,那时间复杂度就是O(1)了。