401. Binary Watch

problem

A binary watch has 4 LEDs on the top which represent the hours (0-11), and the 6 LEDs on the bottom represent the minutes (0-59).

Each LED represents a zero or one, with the least significant bit on the right.


For example, the above binary watch reads "3:25".

Given a non-negative integer n which represents the number of LEDs that are currently on, return all possible times the watch could represent.

一个二进制手表
给一个数字n,求在手表上用n个数字可以组成多少时间?

solution

  • 转换成数学组合问题(不是排列)
  • 小时位之和不大于12H(720M),分位之和不大于60m
  • 分位左补0
import itertools
import bisect

class Solution(object):
    def readBinaryWatch(self, num):
        """
        :type num: int
        :rtype: List[str]
        """
        dictTime = { 0:1 , 1:2 , 2:4, 3:8, 4:16, 5:32,  6:60, 7:120, 8:240, 9:480}
        listStrs = []
        for item in itertools.combinations(range(10),num):
            sign = bisect.bisect(item,5)
            sumM = sum(dictTime[i] for i in item[:sign])
            sumH = sum(dictTime[i] for i in item[sign:])
            if sumH >= 720 or sumM >= 60:
                continue
            H,M = divmod(sumH+sumM,60)
            listStrs.append('%d:%02d' % (H, M))
        return listStrs


  • 思路如下
  1. 数学模块求组合
  2. 根据组合计算时间之和(单位分,不符合要求的除去)
  3. 时间之和转换为字符串,返回
  • 这个解法符合常规的思路,但是没有利用到二进制特性

discuss

  • 效率大致提高20%,
  • 有意思的是如果不用格式化输入输出'%d:%02d' % (h, m), 自己拼接字符串还能更快一点
class Solution(object):
    def readBinaryWatch(self, num):
        """
        :type num: int
        :rtype: List[str]
        """
        output = []
        for h in range(12):
          for m in range(60):
            if bin(h * 64 + m).count('1') == num:
              output.append('%d:%02d' % (h, m))
        return output
  • 这个解答里面h * 64 ,为什么可以乘以64?(64符合2进制,但是符合小时60进位条件么?)
  • 这个64的意思不是之前思路的转化为分钟,而是单纯的表示二进制第七位作为初始位
posted @ 2016-10-15 15:34  Salmd  阅读(79)  评论(0)    收藏  举报