目录

0401:二进制手表

力扣第 401 题

题目

二进制手表顶部有 4 个 LED 代表 小时(0-11),底部的 6 个 LED 代表 分钟(0-59)。每个 LED 代表一个 0 或 1,最低位在右侧。

  • 例如,下面的二进制手表读取 "4:51"

给你一个整数 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

分析

#1

  • 可以用二进制代表灯的状态,遍历[1,1«10],判断是否符合
  • 遍历还可以用 Gosper’s Hack,只枚举二进制 k 个 1 的数
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
class Solution:
    def readBinaryWatch(self, turnedOn: int) -> List[str]:
        res = []
        st = (1<<turnedOn)-1
        while st<(1<<10):
            a,b = st>>6,st&63
            if a<12 and b<60:
                res.append('%d:%02d'%(a,b))
            lb = st&-st
            r = st+lb
            st = (r^st)>>(lb.bit_length()+1)|r
            if st==0:
                break
        return res

41 ms

#2

  • 数据量较小,因此可以逆向思维,直接遍历所有有效时间,计算亮灯个数

解答

1
2
3
4
5
6
7
A = [[] for _ in range(11)]
for a,b in product(range(12),range(60)):
    A[a.bit_count()+b.bit_count()].append('%d:%02d'%(a,b))

class Solution:
    def readBinaryWatch(self, turnedOn: int) -> List[str]:
        return A[turnedOn]

38 ms