题目:
题目链接:https://leetcode-cn.com/problems/binary-watch/
解题思路:
"所有可能",第一反应就是回溯 + 剪枝的方式
但是同时回溯小时和分钟的逻辑似乎比较复杂
所以采用了分别递归回溯小时和分钟的方式,然后再两两配对组合最终的时间
同时也可以减少递归的层数,减少内存消耗
代码实现:
class Solution:
def readBinaryWatch(self, num: int) -> List[str]:
def get_num(path):
num = 0
for index, a in enumerate(path):
if 1 == a:
num += pow(2, len(path) - 1 - index)
return num
def create_res(left_num, total_num, max_num, path, res):
"""
left_num : 剩余可以填入1的个数
total_num : path应该有的长度
max_num : 限制最大时间,小时不应该超过11,分钟不应该超过59
path : 当前遍历的路径
res : 遍历结果
"""
# 如果剩余可以填入1的个数为0,并且path的总长度符合要求,加入结果集并剪枝退出
if left_num == 0 and total_num == len(path):
num = get_num(path)
if num <= max_num:
res.append(str(num))
return
# 如果path的长度超过了总长度,说明不应该继续遍历了,退出
elif len(path) > total_num:
return
# 如果还有剩余可以填入1的个数,则遍历1的可能性
# 并且在遍历时,更新left_num的值
if left_num > 0:
path.append(1)
create_res(left_num - 1, total_num, max_num, path, res)
path.pop()
# 继续探索0的可能性
path.append(0)
create_res(left_num, total_num, max_num, path, res)
path.pop()
res = []
for hour in range(0, min(4, num) + 1):
minute = num - hour
if minute > 6:
continue
hour_res = []
minute_res = []
create_res(hour, 4, 11, [], hour_res)
create_res(minute, 6, 59, [], minute_res)
for curr_hour in hour_res:
for curr_min in minute_res:
# 两两组合成最终的时间
res.append(curr_hour + ':' + curr_min.rjust(2, '0'))
return res