题目
二进制手表顶部有 4
个 LED
代表小时(0-11)
,底部的 6
个 LED
代表分钟(0-59)
。
每个 LED
代表一个 0
或 1
,最低位在右侧。
例如,上面的二进制手表读取
3
:
25
3:25
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"]
函数原型
char ** readBinaryWatch(int num, int* returnSize){}
边界判断
char ** readBinaryWatch(int num, int* returnSize){}
算法设计:枚举
思路:枚举,符合条件的排列组合。
L
E
D
LED
LED 只有 2
种状态,亮 or
灭,二进制的
1
o
r
0
1~or~0
1 or 0。
题目说, n n n 代表 L E D LED LED 亮着的数量,其实也就是 1 1 1 的数量。
- 那些小时
1
的个数 + 那些分钟1
的个数 =n
int cnt_one(int n) { // 统计 1 的位数
int cnt = 0;
while( n != 0 ){
n &= (n-1);
cnt ++;
}
return cnt;
}
char ** readBinaryWatch(int num, int* returnSize){
// 先开辟行
char **p = (char **)malloc(sizeof(char*) * 1024);
// 再开辟列
for (int i = 0; i < 1024; i++)
p[i] = (char *)malloc(sizeof(char) * 6);
// 最大如 11:59,也才 5 个字符
int cnt = 0;
for(int h=0; h<12; h++) // 枚举小时,题目说最大为 11
for(int m=0; m<60; m++) // 枚举分钟,分钟是60进制 [0,59]
if( cnt_one(h) + cnt_one(m) == num ) // 枚举核心,状态表达
sprintf(p[cnt++], "%d:%02d", h, m);
// %d:%02d 是时钟的格式,%02 会自动补零,如 1:1 会补成 1:01
*returnSize = cnt;
return p;
}
枚举的复杂度:
- 时间复杂度: Θ ( n 2 ) \Theta(n^{2}) Θ(n2)
- 空间复杂度:
Θ
(
1
)
\Theta(1)
Θ(1)