1、问题描述
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.
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".
2、边界条件:1、num比较大的情况,在前面就可以处理掉,后面就可以不用考虑了;2、num = 0的情况;3、num<0不考虑,其他也在hour的循环里面过滤掉了。
3、思路:1、先确定hour的亮灯数,for循环;2、num - hour即为min的亮灯数,校验一下合法性;3、用递归的方法,分别求出hour和min的亮灯组合;4、最后将hour和min组合起来。
递归子函数思路:1、来到一个位置,有两种选择-亮灯或者不亮灯;2、选择不亮灯,亮灯数不变,index+1,但是有限制条件--剩余位置>剩余亮灯数,否则必须选择亮灯;3、选择亮灯,亮灯数-1,index+1;4、进入下一层。
base case:亮灯数==0,1、把int[] 记录的亮灯分布,计算成时/分;2、hour不用多处理,直接转为String保存,min需要判断>9?决定是否添0。
4、代码实现
class Solution { public List<String> readBinaryWatch(int num) { List<String> results = new ArrayList<>(); for (int hourLedOnNum = 0; hourLedOnNum < 4 && hourLedOnNum <= num; hourLedOnNum++) { int minLedOnNum = num - hourLedOnNum; if (minLedOnNum >= 6) { continue; } List<String> hours = new ArrayList<>(); int[] hourLeds = {0, 0, 0, 0}; timeCombs(hours, hourLeds, hourLedOnNum, 0); List<String> mins = new ArrayList<>(); int[] minLeds = {0, 0, 0, 0, 0, 0}; timeCombs(mins, minLeds, minLedOnNum, 0); results.addAll(watchCombs(hours, mins)); } return results; } public void timeCombs(List<String> times, int[] leds, int ledOnNum, int index) { if (ledOnNum == 0 || index == leds.length) {//后面条件可以去掉 //record reuslts int time = 0; for (int i = 0; i < leds.length; i++) { time += leds[i] << i; } if ((leds.length == 4 && time > 11) || (leds.length == 6 && time > 59)) { return; } if (leds.length == 6 && time < 10) {//min小于10需要加0 times.add("0" + Integer.toString(time)); } else { times.add(Integer.toString(time));//Integer.toString(int i) int i 转成 String } return; } if (ledOnNum < leds.length - index) { timeCombs(times, leds, ledOnNum, index + 1); //not choose } leds[index] = 1; //choose timeCombs(times, leds, ledOnNum - 1, index + 1); leds[index] = 0; } public List<String> watchCombs(List<String> hours, List<String> mins) { List<String> results = new ArrayList<>(); for (int i = 0; i < hours.size(); i++) { for (int j = 0; j < mins.size(); j++) { results.add(hours.get(i) + ":" + mins.get(j)); } } return results; } }
5、时间复杂度:; 空间复杂度:
6、主要api:
int类型转成String:String Integer.toString(int i),i是被转换,返回值为StringInteger类型转为String: Integer i = new Integer(); String str = i.toString();类似的还有 Character.toString(char c); Character ch = new Character(); ch.toString();
7、其他解法:从结果上面筛选,数一下bit数
public List<String> readBinaryWatch(int num) { ArrayList<String> result = new ArrayList<>(); for (int i = 0; i < 12; i++) { for (int j = 0; j < 60; j++) { if (Integer.bitCount(i) + Integer.bitCount(j) == num) { result.add(String.format("%d:%02d", i, j)); } } } return result; }