文章题目来源于leetcode,解法学习了讨论去的解法。
问题:有一种二进制LED表。上面的4个LED灯表示小时,下面6个LED灯表示分钟。给定一个int值,写出可能表示的时间。例如输入1,
Input: n = 1
Return: [“1:00”, “2:00”, “4:00”, “8:00”, “0:01”, “0:02”, “0:04”, “0:08”, “0:16”, “0:32”]
注意:1输出结果的顺序无所谓;2 小时不能有高位0,例如”01:00”是错误的,”1:00”是正确的;3 分钟用两位数表示,例如”1:1”是错误的,”1:01”是正确的。
思路:这是一道典型的深度优先搜索,枚举各种情况就好了。枚举所有小时的可能性,再枚举所有分钟的可能性。我确定我会做,但是失败了。因为我同时在枚举小时和分钟。以前处理的都是单个的枚举。
// 每一步消耗一个数,同时枚举小时和分钟,结果错误,有重复的情况。private void visit(int num, int countHour, int countMinute, int startHourIndex, int startMinuteIndex) {if (num == 0) {if (countHour < 12) {String str = countHour + ":" + (countMinute < 10 ? "0" + countMinute : countMinute);if (!list.contains(str)) {list.add(str);}}} else {if (startMinuteIndex < mininutes.length) {visit(num - 1, countHour, countMinute + mininutes[startMinuteIndex], startHourIndex, startMinuteIndex + 1);visit(num, countHour, countMinute, startHourIndex, startMinuteIndex + 1);}if (startHourIndex < hours.length) {visit(num - 1, countHour + hours[startHourIndex], countMinute, startHourIndex + 1, startMinuteIndex);visit(num, countHour, countMinute, startHourIndex + 1, startMinuteIndex);}}}
收获:
1 看了别人的解决方案后,分别枚举小时、分钟,最后再组合到一起。
2 还有一种方法更牛。提前把所有小时的可能组合、所有分钟可能的组合列出来。然后再把小时、分钟组合。参考链接。
private int[] hours = new int[] { 1, 2, 4, 8 };private int[] mininutes = new int[] { 1, 2, 4, 8, 16, 32 };private List<String> list;public List<String> readBinaryWatch(int num) {list = new ArrayList<String>();for (int i = 0; i <= num; i++) {List<Integer> hours = visitHour(i);List<Integer> minutes = visitMinute(num - i);for (Integer h : hours) {if (h < 12) {for (Integer m : minutes) {if (m < 60) {list.add(h + ":" + (m < 10 ? "0" + m : m));}}}}}return list;}private List<Integer> visitMinute(int num) {List<Integer> list = new ArrayList<Integer>();visit2(num,0,0,list,mininutes);return list;}private List<Integer> visitHour(int num) {List<Integer> list = new ArrayList<Integer>();visit2(num,0,0,list,hours);return list;}private void visit(int num,int count, int startIndex, List<Integer> list,int[] nums) {if(num<=0){list.add(count);return;}if(startIndex>=nums.length){return;}visit(num-1,count+nums[startIndex],startIndex+1,list,nums);visit(num,count,startIndex+1,list,nums);}/*** visit的另外一种写法* @param num* @param count* @param startIndex* @param list* @param nums*/private void visit2(int num,int count, int startIndex, List<Integer> list,int[] nums) {if(num<=0){list.add(count);return;}for(int i=startIndex;i<nums.length;i++){visit2(num-1,count+nums[i],i+1,list,nums);}}
参考资料:
1 [题目](https://leetcode.com/problems/binary-watch/#/description)
2 讨论1
3 讨论2