leetcode-401.二进制手表
[401] 二进制手表
https://leetcode-cn.com/problems/binary-watch/description/
algorithms
Easy (48.85%)
Likes: 73
Dislikes: 0
Total Accepted: 5.2K
Total Submissions: 10.6K
Testcase Example: '0'
二进制手表顶部有 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”。
from typing import List
class Solution:
def __init__(self):
self.result_all = None
self.nums = [1, 2, 4, 8, 1, 2, 4, 8, 16, 32] # 对应的 [0-9] 个选项中的字
self.visited = [0 for _ in range(len(self.nums))] # 记录已访问过的元素
def readBinaryWatch(self, num: int) -> List[str]: # 指定返回值为List[str]类型
self.result_all = []
self.__dfs(num, 0, 0)
return self.result_all
def __dfs(self, num, step, start): # dfs 回溯,参数变量:step -> 递归深度,start -> 可选择项的开始位置 (组合类回溯,常用)
if step == num: # 到达叶子节点,无返回值dfs,在叶子节点结算
self.result_all.append(self.__handler())
for i in range(start, len(self.nums)): # * 注意 start 变量, 组合类 回溯,避免重复
self.visited[i] = 1 # 先设置已访问
if not self.__is_vaild(): # 剪枝,判断是否满足需求
self.visited[i] = 0
continue
self.__dfs(num, step + 1, i + 1) # 进入下一次递归,step深度加1,开始位置加1
self.visited[i] = 0 # 回溯点
def __is_vaild(self): # 判断是否为有效值
sum_h = 0
sum_m = 0
for i in range(len(self.visited)):
if not self.visited[i]:
continue
if i < 4:
sum_h += self.nums[i]
else:
sum_m += self.nums[i]
return sum_h <= 11 and sum_m <= 59
def __handler(self): # 处理结果,题目要求的输出格式
sum_h = 0
sum_m = 0
for i in range(len(self.visited)):
if not self.visited[i]:
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__":
# print(Solution().readBinaryWatch(1))