[LeetCode By Go 54]401. Binary W
题目
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.
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)
}
}