題目描述
同樣的道理,拿到題目一點頭緒都沒,一開始考慮的是組合成一個二級制,因爲分鐘爲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];//回退
}
}
}
}