[LeetCode By Go 54]401. Binary Watch

题目

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.

《[LeetCode By Go 54]401. Binary Watch》 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.

Example:

Input: n = 1
Return: [“1:00”, “2:00”, “4:00”, “8:00”, “0:01”, “0:02”, “0:04”, “0:08”, “0:16”, “0:32”]

Note:

  • The order of output does not matter.
  • The hour must not contain a leading zero, for example “01:00” is not valid, it should be “1:00”.
  • The minute must be consist of two digits and may contain a leading zero, for example “10:2” is not valid, it should be “10:02”.

解题思路

遍历所有可能情况,一共有12*60种情况,判断二进制数中出现1的次数是否和输入相等,若相等按照格式将时间放入结果数组

快速法求一个二进制数中1的个数

其运算次数与输入n的大小无关,只与n中1的个数有关。如果n的二进制表示中有k个1,那么这个方法只需要循环k次即可。其原理是不断清除n的二进制表示中最右边的1,同时累加计数器,直至n为0,代码如下

int BitCount2(unsigned int n)
{
    unsigned int c =0 ;
    for (c =0; n; ++c)
    {
        n &= (n -1) ; // 清除最低位的1
    }
    return c ;
}

为什么n &= (n – 1)能清除最右边的1呢?因为从二进制的角度讲,n相当于在n – 1的最低位加上1。举个例子,8(1000)= 7(0111)+ 1(0001),所以8 & 7 = (1000)&(0111)= 0(0000),清除了8最右边的1(其实就是最高位的1,因为8的二进制中只有一个1)。再比如7(0111)= 6(0110)+ 1(0001),所以7 & 6 = (0111)&(0110)= 6(0110),清除了7的二进制表示中最右边的1(也就是最低位的1)。

代码

ReadBinaryWatch.go

package _401_Binary_Watch

import (
    "fmt"
)

func BitCount(num int) (c int) {
    for c = 0; num != 0; c++ {
        num = num & (num - 1)
    }

    return c
}

func ReadBinaryWatch(num int) []string {
    var times []string
    for i := 0; i < 12 ; i++ {
        for j := 0; j < 60; j++ {
            tmp := i * 64 + j
            bitCount := BitCount(tmp)

            if num == bitCount {
                time := fmt.Sprintf("%d:%02d", i, j)
                times = append(times, time)
            }
        }

    }

    return  times
}

测试

ReadBinaryWatch_test.go

package _401_Binary_Watch

import (
    "testing"
    "fmt"
)

func TestReadBinaryWatch(t *testing.T) {
    var tests = []struct{
        input int
    } {
        {0},
        {1},
    }

    for _, v := range tests {
        ret := ReadBinaryWatch(v.input)

        fmt.Printf("ret:%+v\n", ret)
    }
}
    原文作者:miltonsun
    原文地址: https://www.jianshu.com/p/1dcece388514
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞