86、二进制手表

本文探讨了二进制手表的时间解析问题,通过枚举和回溯法两种策略,详细解析了如何根据点亮的LED数量计算所有可能的时间显示。介绍了使用Java的BitCount函数简化计算,以及通过递归回溯实现的高效算法。
摘要由CSDN通过智能技术生成

题目描述
在这里插入图片描述
在这里插入图片描述
同样的道理,拿到题目一点头绪都没,一开始考虑的是组合成一个二级制,因为分钟为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];//回退
            }
        }
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值