401 binary watch

 文章题目来源于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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值