本文旨在对于个人知识的梳理以及知识的分享,如果有不足的地方,欢迎大家在评论区指出
题目描述
二进制手表顶部有 4 个 LED 代表 小时(0-11),底部的 6 个 LED 代表 分钟(0-59)。每个 LED 代表一个 0 或 1,最低位在右侧。
例如,下面的二进制手表读取 “3:25” 。
给你一个整数 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
题目链接
题目分析
这道题有两种做法,我的做法在标准做法面前显得有些"丑陋",我采用了二进制枚举的方式,也就是回溯的方式,枚举小时以及分钟的所有状态,找到合法且数量恰好等于turnedOn
的所有情况,时间复杂度为
O
(
2
4
∗
4
∗
2
6
∗
6
)
O(2^4*4*2^6*6)
O(24∗4∗26∗6),标准的做法是直接枚举合法的小时和分钟,找到开启灯的数量恰好为turnedOn
的所有情况,二者的本质区别在于第一种情况枚举了大量的无用状态。
解题代码
Go
标准做法
package main
var res []string
func getBit(x int) int {
res := 0
for x != 0 {
res += 1
x -= (x&-x)
}
return res
}
func readBinaryWatch(turnedOn int) []string {
res = make([]string, 0)
for h:=0; h<12; h++ {
for m:=0; m<60; m++ {
if getBit(h) + getBit(m) == turnedOn {
res = append(res, fmt.Sprintf("%d:%02d", h, m))
}
}
}
return res
}
个人解法
package main
var hour = []int{1, 2, 4, 8}
var minute = []int{1, 2, 4, 8, 16, 32}
var res []string
func readBinaryWatch(turnedOn int) []string {
res = make([]string, 0)
for i := 0; i < 1<<len(hour); i++ {
hourNum, curHour := 0, 0
for j := 0; j < len(hour); j++ {
if ((i >> j) & 1) == 1 {
hourNum += 1
curHour += hour[j]
}
}
if hourNum > turnedOn || curHour > 11 {
continue
}
for m := 0; m < 1<<len(minute); m++ {
minuteNum, curMinute := 0, 0
for n := 0; n < len(minute); n++ {
if ((m>>n)&1) == 1 {
minuteNum += 1
curMinute += minute[n]
}
}
if minuteNum > turnedOn-hourNum || curMinute > 59 {
continue
}
if minuteNum + hourNum == turnedOn {
res = append(res, fmt.Sprintf("%d:%02d", curHour, curMinute))
}
}
}
return res
}