[leetcode_401]401. 二进制手表

401. 二进制手表

https://leetcode-cn.com/problems/binary-watch/

难度简单232收藏分享切换为英文接收动态反馈

二进制手表顶部有 4 个 LED 代表 小时(0-11),底部的 6 个 LED 代表 分钟(0-59)

每个 LED 代表一个 0 或 1,最低位在右侧。

img

例如,上面的二进制手表读取 “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”。
  • 超过表示范围(小时 0-11,分钟 0-59)的数据将会被舍弃,也就是说不会出现 “13:00”, “0:61” 等时间。

解法1 递归 + 回溯法

暴力递归法

from typing import List


class Solution:

    def readBinaryWatch(self, num: int) -> List[str]:
        """
        :type num: int
        :rtype: List[str]
        """
        self.results = []
        # 0,1,2,3 代表小时
        # 4 5 ..., 8, 9 代表分钟
        self.nums = [1, 2, 4, 8, 1, 2, 4, 8, 16, 32]

        self.length = len(self.nums)
        # 当前 表盘的数字被选择,被选择标记为1,没有被选择标记为0;
        # [0,,3]表示小时,  [4,,,9]表示分钟
        self.choice = [0] * self.length

        self._generate(num, 0, 0)
        return self.results

    def _generate(self, num: int, level: int, start: int):
        #  terminator
        if level == num:
            self.results.append(self._convert_time(self.choice))
            return

        for i in range(start, len(self.nums)):
            self.choice[i] = 1

            if not self._is_valid_time(self.choice):
                # 不满足条件,后面的数字不用继续看了, 同时把当前结果是为零
                self.choice[i] = 0
                continue
            # drill down
            self._generate(num, level + 1, i + 1)
            # revert the current level status
            self.choice[i] = 0

    def _is_valid_time(self, visited) -> bool:
        """
        是否满足时间的 限制 ,满足返回True, 不满足返回False
        :param visited:
        :return:
        """
        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 _convert_time(self, choice):
        sum_h = 0
        sum_m = 0
        for i in range(self.length):
            if choice[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


if __name__ == '__main__':
    r = Solution().readBinaryWatch(num=1)
    print(r)
    pass

解法2

直接根据 数字获取对应二进制1 的数量, 如果数量为 num 那么就是要求的解, 然后在转成时间格式即可。


class Solution:

    def readBinaryWatch(self, num: int) -> List[str]:
        """
        :type num: int
        :rtype: List[str]
        """
        results = []
        for i in range(0, 12):
            for j in range(0, 60):
                if self._hammingWeight(i) + self._hammingWeight(j) == num:
                    r = "%d" % i + ":" + "%02d" % j
                    results.append(r)

        return results

    def _hammingWeight(self, n: int) -> int:
        """
        获取n 对应二进制1的个数
        :param n:
        :return:
        """
        count = 0
        while n:
            # print(bin(n))
            count += 1
            n = n & n - 1
        return count


分享快乐,留住感动. '2021-03-20 21:30:56' --frank
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值