LeetCode-401. Binary Watch

本文介绍了一种特殊的二进制手表工作原理,并提供两种C++实现方案来解决给定LED亮灯数量时所有可能的时间表示问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Description

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

1.The order of output does not matter.
2.The hour must not contain a leading zero, for example "01:00" is not valid, it should be "1:00".
3.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".

Solution 1(C++)

class Solution {
    void backtrack(int num, vector<int> bin, vector<string>& res, int index){
        if(num==0){
            int hour=0, minute=0, i;
            for(i=0; i<4; i++){
                hour = hour*2+bin[i];
            }
            for(i=4; i<10; i++){
                minute = minute*2+bin[i];
            }
            if(hour<12 && minute<60){
                string time="";
                time.append(to_string(hour)); time.append(":");
                if(minute<10) time.append("0"+to_string(minute));
                else time.append(to_string(minute));
                res.push_back(time);
            }
            else return;
        }
        else{
            for(int i=index; i<10; i++){
                bin[i]=1; num -= 1;
                backtrack(num, bin, res, i+1);
                bin[i]=0; num += 1;
            }
        }
    }
public:
    vector<string> readBinaryWatch(int num) {
        vector<string> res;
        vector<int> bin(10,0);
        backtrack(num, bin, res, 0);
        return res;
    }
};

Solution 2(C++)

class Solution {
public:
    vector<string> readBinaryWatch(int num) {
        vector<int> m = {1,2,4,8,16,32};
        vector<int> h = {1,2,4,8};
        vector<string> res;

        for (int i = 0; i <= num; i++) {
            vector<int> hour = getTime(i, h);
            vector<int> min = getTime(num - i, m);
            for (auto h : hour) {
                if (h > 11) continue;
                for (auto m : min) {
                    if (m > 59) continue;
                    res.push_back(to_string(h) + ":" + (m<10? "0":"") + to_string(m));
                }
            }
        }

        return res;
    }

    vector<int> getTime(int digits, vector<int> &value) {
        vector<int> res;
        helper(res, 0, digits, 0, 0, value);
        return res;
    }

    void helper(vector<int> &res, int start, int digits, int sum, int used, vector<int> &value) {
        if (used == digits) {
            res.push_back(sum);
            return;
        }
        for (int i = start; i < value.size(); i++) {
            helper(res, i+1, digits, sum+value[i], used + 1, value);
        }
    }
};

算法分析

回溯的问题目前我觉得还是有套路的。相同类型题目Easy难度有:LeetCode-784. Letter Case Permutation。当然可以对比着看。

目前就我自己总结的回溯基本套路,当然有可能只限于Easy难度。

首先说一下什么类型的问题可以考虑使用回溯。目前,在我看来,就是排列组合问题适用于回溯。很简单,Easy的两个题都是排列组合。甚至深度优先搜索,广度优先搜索也是先排列组合出所有情况,然后从中选择适合要求的,比如最短路径、或者本题中不超过上限的。

具体的套路就是,一般单独写一个回溯函数。这样主函数中直接调用回溯函数就可以了。

回溯函数目前都设为无返回值的。所以回溯函数参数一般有要返回的结果。还要有题目的输入。

回溯函数体一般由两部分构成,一部分是回溯到底的结果返回处理部分,一部分是回溯部分。结果返回处理部分一般根据实际情况分析,然后实现具体代码。回溯部分可以简单有三步完成:

第一步:做标记,进行尝试。比如此题中,就是由0变1,num减1,上一题中就是字母大小写变化、
第二步:回溯,更新回溯函数参数,然后进行回溯迭代。
第三步:取消标记。比如此题中,将1变回0,num加1,上一题就是字母变回原来大小写形式。

程序分析

略。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值