题目描述
同样的道理,拿到题目一点头绪都没,一开始考虑的是组合成一个二级制,因为分钟为5位,时钟为4位,但是那样实在时复杂啊
注意的时Java的Bitcount计算的是n的二级制中1的个数
class Solution {
public List<String> readBinaryWatch(int num) {
List<String> times = new ArrayList<>();
if(num == 0){
times.add("0:00");
return times;
}
for (int h = 0; h < 12; h++)
for (int m = 0; m < 60; m++)
if (Integer.bitCount(h) + Integer.bitCount(m) == num)
times.add(String.format("%d:%02d", h, m));
return times;
}
}
其实根据这个就能将其枚举弄出来,然后放入枚举即可
排名靠前的代码:看其思路,虽然现在不是很懂,但是要慢慢了解
class Solution {
public List<String> readBinaryWatch(int num) {
//回溯法
int[] time = {1,2,4,8,1,2,4,8,16,32};//记录可能的亮灯值
List<String> list = new ArrayList<>();//记录所有可能的亮灯数
helper(list,num,0,0,time,0);//辅助函数,
// 用于递归回溯,hour :代表当前的小时表示,second:代表当前的分钟表示,
// time用于记录每个位置灯亮表示的值,start,表示当前启动位置
return list;
}
void helper(List<String> list,int num,int hour,int second,int[] time,int start){
if(num == 0){//如果亮灯数变为0,则表示找到一组时间表示,加入最终的结果集list
if(second < 10)//分钟小于10时特殊处理格式
list.add(hour + ":0" + second);
else
list.add(hour + ":" + second);
return;//找到一个值,结束当前递归
}
for(int i = start;i < time.length;i++){//当前num不为0,即还有可以亮灯
if(i < 4){//如果起始位置还没有超过小时的表示范围,则小时亮一个灯
hour = hour + time[i];//加上当前的小时
if(hour < 12)//如果小时亮灯后还小于12,最大可表示11,则num -1,i+1后
// 递归调用,直到找到num==0时的一个时间表示
helper(list,num-1,hour,second,time,i+1);
hour = hour - time[i];//回退,找到当前状态的一组解后,回退到上一个状态,
// 继续搜索下一个可能的解
}
else {//小时可能表示的时间搜索完后,搜索分钟能表示的时间
second = second + time[i];//把前一步结果加上
if(second < 60)//如果分钟小于60,最大是59,则在当前状态,继续下一搜索,
// num -1,i + 1,
helper(list,num - 1,hour,second,time,i+1);
second = second - time[i];//回退
}
}
}
}