[M模拟] lc401. 二进制手表(模拟+位运算技巧+sprintf()技巧+二进制枚举)

1. 题目来源

链接:401. 二进制手表

2. 题目解析

模拟就行了。

总共 10 个灯,枚举这 10 个灯的亮、灭情况即可。

由于本题需要使用格式化输出,所有可以用 sprintf() 来简化代码。

利用位运算巧妙取出前 4 位和后六位的二进制数的 10 进制表示。


时间复杂度: O ( 2 10 ) O(2^{10}) O(210)

空间复杂度: O ( n ) O(n) O(n)


sprintf() 格式化输出:

class Solution {
public:
    vector<string> readBinaryWatch(int turnedOn) {
        vector<string> res;
        char str[10];
        for (int i = 0; i < 1 << 10; i ++ ) {
            int t = 0;
            for (int k = i; k; k -= k & -k) t ++ ;
            if (t == turnedOn) {
                int h = i >> 6, m = i & 63;   // 位运算技巧,返回小时(高四位),分钟(低六位)
                if (h < 12 && m < 60) {
                    sprintf(str, "%d:%02d", h, m);	// 组织成字符串放入 str 字符数组中
                    res.push_back(str);
                }
            }
        }

        return res;
    }
};

二进制枚举:

class Solution {
public:
    vector<string> readBinaryWatch(int turnedOn) {
        vector<string> res;

        for (int i = 0; i < 1 << 4; i ++ ) 
            for (int j = 0; j < 1 << 6; j ++ ) {
                int t = 0, h = 0, m = 0;
                for (int k = 31; ~k; k -- ) {
                    int c = i >> k & 1;
                    h = h * 2 + c;
                    if (c) t ++ ;
                }

                for (int k = 31; ~k; k -- ) {
                    int c = j >> k & 1;
                    m = m * 2 + c;
                    if (c) t ++ ;
                }

                if (t != turnedOn) continue;
                if (m >= 60 || h >= 12) continue;

                string s;
                s += to_string(h);
                s += ":";
                if (m < 10) s += '0', s += to_string(m);
                else s += to_string(m);

                res.push_back(s);
            } 

        return res;
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Ypuyu

如果帮助到你,可以请作者喝水~

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值