401. 二进制手表
https://leetcode-cn.com/problems/binary-watch/
难度简单232收藏分享切换为英文接收动态反馈
二进制手表顶部有 4 个 LED 代表 小时(0-11),底部的 6 个 LED 代表 分钟(0-59)。
每个 LED 代表一个 0 或 1,最低位在右侧。
例如,上面的二进制手表读取 “3:25”。
给定一个非负整数 n 代表当前 LED 亮着的数量,返回所有可能的时间。
示例:
输入: n = 1
返回: ["1:00", "2:00", "4:00", "8:00", "0:01", "0:02", "0:04", "0:08", "0:16", "0:32"]
提示:
- 输出的顺序没有要求。
- 小时不会以零开头,比如 “01:00” 是不允许的,应为 “1:00”。
- 分钟必须由两位数组成,可能会以零开头,比如 “10:2” 是无效的,应为 “10:02”。
- 超过表示范围(小时 0-11,分钟 0-59)的数据将会被舍弃,也就是说不会出现 “13:00”, “0:61” 等时间。
解法1 递归 + 回溯法
暴力递归法
from typing import List
class Solution:
def readBinaryWatch(self, num: int) -> List[str]:
"""
:type num: int
:rtype: List[str]
"""
self.results = []
# 0,1,2,3 代表小时
# 4 5 ..., 8, 9 代表分钟
self.nums = [1, 2, 4, 8, 1, 2, 4, 8, 16, 32]
self.length = len(self.nums)
# 当前 表盘的数字被选择,被选择标记为1,没有被选择标记为0;
# [0,,3]表示小时, [4,,,9]表示分钟
self.choice = [0] * self.length
self._generate(num, 0, 0)
return self.results
def _generate(self, num: int, level: int, start: int):
# terminator
if level == num:
self.results.append(self._convert_time(self.choice))
return
for i in range(start, len(self.nums)):
self.choice[i] = 1
if not self._is_valid_time(self.choice):
# 不满足条件,后面的数字不用继续看了, 同时把当前结果是为零
self.choice[i] = 0
continue
# drill down
self._generate(num, level + 1, i + 1)
# revert the current level status
self.choice[i] = 0
def _is_valid_time(self, visited) -> bool:
"""
是否满足时间的 限制 ,满足返回True, 不满足返回False
:param visited:
:return:
"""
sum_h = 0
sum_m = 0
for i in range(len(visited)):
if visited[i] == 0:
continue
if i < 4:
sum_h += self.nums[i]
else:
sum_m += self.nums[i]
return 0 <= sum_h <= 11 and 0 <= sum_m <= 59
def _convert_time(self, choice):
sum_h = 0
sum_m = 0
for i in range(self.length):
if choice[i] == 0:
continue
if i < 4:
sum_h += self.nums[i]
else:
sum_m += self.nums[i]
result = "" + str(sum_h) + ":"
if sum_m < 10:
result += "0" + str(sum_m)
else:
result += str(sum_m)
return result
if __name__ == '__main__':
r = Solution().readBinaryWatch(num=1)
print(r)
pass
解法2
直接根据 数字获取对应二进制1 的数量, 如果数量为 num 那么就是要求的解, 然后在转成时间格式即可。
class Solution:
def readBinaryWatch(self, num: int) -> List[str]:
"""
:type num: int
:rtype: List[str]
"""
results = []
for i in range(0, 12):
for j in range(0, 60):
if self._hammingWeight(i) + self._hammingWeight(j) == num:
r = "%d" % i + ":" + "%02d" % j
results.append(r)
return results
def _hammingWeight(self, n: int) -> int:
"""
获取n 对应二进制1的个数
:param n:
:return:
"""
count = 0
while n:
# print(bin(n))
count += 1
n = n & n - 1
return count