題目
難度:★★☆☆☆
類型:數(shù)學(xué)
二進制手表頂部有 4 個 LED 代表小時(0-11),底部的 6 個 LED 代表分鐘(0-59)。
每個 LED 代表一個 0 或 1,最低位在右側(cè)。

例如,上面的二進制手表讀取 “3:25”。
給定一個非負整數(shù) n 代表當(dāng)前 LED 亮著的數(shù)量,返回所有可能的時間。
示例
輸入: n = 1
返回: ["1:00", "2:00", "4:00", "8:00", "0:01", "0:02", "0:04", "0:08", "0:16", "0:32"]
注意事項
輸出的順序沒有要求。
小時不會以零開頭,比如 “01:00” 是不允許的,應(yīng)為 “1:00”。
分鐘必須由兩位數(shù)組成,可能會以零開頭,比如 “10:2” 是無效的,應(yīng)為 “10:02”。
解答
方案1:暴力求解
我們考慮一天當(dāng)中每一分鐘對應(yīng)的時刻手表上亮燈的個數(shù)并統(tǒng)計,如果遇到亮燈個數(shù)等于指定數(shù)目,那么就把該時刻按照題目要求格式化的時間字符串加入結(jié)果列表中。
暴力法考慮的情況不算多,只有12*60=720個循環(huán),可以通過題目測試。
class Solution:
def readBinaryWatch(self, num):
# 標準化時間輸出
convert_to_string = lambda hour, minute: "{}:{}".format(hour, str(minute).zfill(2))
# 統(tǒng)計數(shù)字n轉(zhuǎn)為二進制后1的個數(shù)
def count_ones(n):
ans = 0
while n > 0:
n = n & (n - 1)
ans += 1
return ans
ans = []
for h in range(12): # 遍歷每一個小時
for m in range(60): # 遍歷每一分鐘
if num == (count_ones(h) + count_ones(m)): # 如果小時和分鐘亮燈的個數(shù)和等于輸入
ans.append(convert_to_string(h, m)) # 那么添加結(jié)果
return ans
方案2:回溯法
這里引用力扣官網(wǎng)中的題解部分,由jawhiow提出,感興趣的同學(xué)可以參考一下。
這是一道比較實際的題目,由于我們不知道具體n為幾,所以用回溯算法是比較合適的。
題目分析
而題目中由于限定了頂部的四個代表了0-11小時,底部的0-59代表分鐘。所以我們不用考慮進位的問題。所以當(dāng)有超過這個限制的,我們需要進行剪枝,否則最后的結(jié)果就錯了。
遞歸結(jié)構(gòu)
r(n)=r(n-1)+w, w代表從nums中選出一個數(shù)字。
遞歸邊界
n == step
遞歸參數(shù)
n:亮燈數(shù)量
step:遞歸層數(shù)
start:開始節(jié)點
result:單次結(jié)果
result_all:最終結(jié)果
其他處理
- 分別計算小時和分鐘,若超過0-11和0-59,則進行剪枝,所以需要寫一個函數(shù),判斷當(dāng)前合不合理
- 將所有燈組成nums=[1, 2, 4, 8, 1, 2, 4, 8, 16, 32]=[0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
- 寫一個函數(shù),將nums處理成正確的時間
答案
class Solution(object):
def __init__(self):
self.result_all = None
self.nums = [1, 2, 4, 8, 1, 2, 4, 8, 16, 32]
self.visited = None
def readBinaryWatch(self, num):
"""
:type num: int
:rtype: List[str]
"""
self.result_all = []
self.visited = [0 for _ in range(len(self.nums))]
self.dfs(num, 0, 0)
return self.result_all
def dfs(self, num, step, start):
if step == num:
self.result_all.append(self.handle_date(self.visited))
return
for i in range(start, len(self.nums)):
self.visited[i] = 1
if not self.calc_sum(self.visited):
self.visited[i] = 0
continue
self.dfs(num, step + 1, i + 1)
self.visited[i] = 0
return
def calc_sum(self, visited):
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 handle_date(self, visited):
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]
result = "" + str(sum_h) + ":"
if sum_m < 10:
result += "0" + str(sum_m)
else:
result += str(sum_m)
return result
如有疑問或建議,歡迎評論區(qū)留言~