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:
- 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".
Solution
Backtrack
跟getCombinations一个思路,注意hour和min都有上限。
class Solution {
public List<String> readBinaryWatch(int num) {
List<String> times = new ArrayList<>();
if (num > 8) {
return times;
}
for (int i = 0; i <= 3; ++i) {
List<Integer> hours = getBinaryList(i, 4, 0);
List<Integer> mins = getBinaryList(num - i, 6, 0);
for (int hour : hours) {
if (hour > 11) { // don't forget overflow
break;
}
for (int min : mins) {
if (min > 59) {
break;
}
times.add(hour + (min < 10 ? ":0" : ":") + min);
}
}
}
return times;
}
public List<Integer> getBinaryList(int i, int n, int sum) {
if (i < 0 || i > n) {
return new ArrayList<>();
}
if (i == 0) {
List<Integer> result = new ArrayList<>();
result.add(sum);
return result;
}
List<Integer> result = getBinaryList(i, n - 1, sum);
int ithBinary = (int) Math.pow(2, n - 1);
result.addAll(getBinaryList(i - 1, n - 1, sum + ithBinary));
return result;
}
}
Optimised: Bit operation, time O(1), space O(1)
其实如果最优解是上面那个的话,这道题就不应该是easy难度了。所以应该使用下面的Optimised解法。
感觉用二进制操作还是挺优雅的哈。这道题目给我的启发是,有时不必直接把所求的集合直接算出来,而是可以从一个大集合中筛选出所求解。
class Solution {
public List<String> readBinaryWatch(int num) {
List<String> times = new ArrayList<String>();
for (int h = 0; h < 12; ++h) {
for (int m = 0; m < 60; ++m) {
if (getDigits(h << 6 | m) != num) {
continue;
}
times.add(h + (m < 10 ? ":0" : ":") + m);
}
}
return times;
}
public int getDigits(int n) {
int digits = 0;
for (int i = 0; i < 32; ++i) {
digits += n & 1;
n >>= 1;
}
return digits;
}
}