Easy
题目描述
二进制手表顶部有 4 个 LED 代表小时(0-11),底部的 6 个 LED 代表分钟(0-59)。每个 LED 代表一个 0 或 1,最低位在右侧。
例如,下面的二进制手表读取 “4:51”。
给你一个整数 turnedOn ,表示当前亮着的 LED 的数量,返回表示手表可能表示的所有可能时间。你可以 按任意顺序 返回答案。
小时不会以零开头:
- 例如,“01:00” 是无效的,应为 “1:00”。
分钟必须由两位数组成,可能会以零开头:
- 例如,“10:2” 是无效的,应为 “10:02”。
示例 1:
输入:turnedOn = 1
输出:["0:01","0:02","0:04","0:08","0:16","0:32","1:00","2:00","4:00","8:00"]
示例 2:
输入:turnedOn = 9
输出:[]
提示:
0 <= turnedOn <= 10
解题思路
这道题有两种主要的解题思路:
方法一:位运算暴力枚举 最直观的方法是枚举所有可能的时间组合,然后检查每个时间对应的二进制表示中有多少个1。小时范围是0-11(4位),分钟范围是0-59(6位)。我们可以遍历所有有效的小时和分钟组合,统计它们二进制表示中1的个数是否等于turnedOn。
方法二:回溯算法 使用回溯的方式,从10个LED位置中选择turnedOn个位置点亮,然后检查对应的时间是否有效。
推荐解法:位运算暴力枚举 考虑到数据规模较小(小时最多12种,分钟最多60种),直接暴力枚举所有可能的时间组合是最简单高效的方法。我们使用内置的位运算函数来计算二进制中1的个数,然后检查小时和分钟的1的个数之和是否等于turnedOn。
时间格式化时需要注意:小时不需要前导零,分钟需要保证两位数格式。
代码实现
class Solution {
public:
vector<string> readBinaryWatch(int turnedOn) {
vector<string> result;
for (int h = 0; h < 12; h++) {
for (int m = 0; m < 60; m++) {
if (__builtin_popcount(h) + __builtin_popcount(m) == turnedOn) {
result.push_back(to_string(h) + ":" + (m < 10 ? "0" : "") + to_string(m));
}
}
}
return result;
}
};
class Solution:
def readBinaryWatch(self, turnedOn: int) -> List[str]:
result = []
for h in range(12):
for m in range(60):
if bin(h).count('1') + bin(m).count('1') == turnedOn:
result.append(f"{h}:{m:02d}")
return result
public class Solution {
public IList<string> ReadBinaryWatch(int turnedOn) {
IList<string> result = new List<string>();
for (int h = 0; h < 12; h++) {
for (int m = 0; m < 60; m++) {
if (CountBits(h) + CountBits(m) == turnedOn) {
result.Add($"{h}:{m:D2}");
}
}
}
return result;
}
private int CountBits(int n) {
int count = 0;
while (n > 0) {
count += n & 1;
n >>= 1;
}
return count;
}
}
/**
* @param {number} turnedOn
* @return {string[]}
*/
var readBinaryWatch = function(turnedOn) {
const result = [];
for (let h = 0; h < 12; h++) {
for (let m = 0; m < 60; m++) {
const hourBits = h.toString(2).split('0').join('').length;
const minuteBits = m.toString(2).split('0').join('').length;
if (hourBits + minuteBits === turnedOn) {
result.push(`${h}:${m.toString().padStart(2, '0')}`);
}
}
}
return result;
};
复杂度分析
| 复杂度类型 | 复杂度 |
|---|---|
| 时间复杂度 | O(1) |
| 空间复杂度 | O(1) |
说明:虽然有双重循环,但循环次数是固定的(12 × 60 = 720),属于常数级别。位运算计算1的个数的时间复杂度也是常数级别。
相关题目
. Number of 1 Bits (Easy)