LeetCode 401 - 二进制手表


文章目录

摘要

这道题其实是一个非常典型的组合枚举问题。我们有 10 个 LED 灯,其中 4 个代表小时(范围 0--11),6 个代表分钟(范围 0--59),题目要求我们给出所有"亮灯数 = turnedOn"时的合法时间组合。

看起来像是个电子表的问题,但本质上是二进制位运算与组合的应用。我们可以把"亮灯的数量"理解成"二进制 1 的个数",所以整个题的核心思路就是:枚举所有可能的小时和分钟组合,筛选出二进制中 1 的个数刚好等于 turnedOn 的情况。

描述

在一个二进制手表上:

  • 上面 4 个 LED 代表小时(0~11),用 4 位二进制来表示;
  • 下面 6 个 LED 代表分钟(0~59),用 6 位二进制来表示。

举例:

  • 小时 4 = 0100
  • 分钟 51 = 110011
    那么时间是 "4:51"

我们要做的就是:给定亮着的灯的数量 turnedOn,输出所有符合这个亮灯数的时间,比如当 turnedOn = 1 时,只有一个 LED 亮着,那么可能是 "1:00""0:08""0:32" 等。

题解答案

最直观的想法是暴力枚举所有可能的小时和分钟:

  • 小时范围 [0, 11]
  • 分钟范围 [0, 59]

对于每个组合:

  1. 计算当前小时和分钟的二进制表示;
  2. 求两者中 1 的总数;
  3. 如果等于 turnedOn,就把格式化后的时间加入结果。

Swift 提供了内置的函数 nonzeroBitCount,可以直接获取一个整数的二进制中 1 的数量,非常适合这种情况。

题解代码分析

下面我们来写一个完整可运行的 Swift Demo:

swift 复制代码
import Foundation

class Solution {
    func readBinaryWatch(_ turnedOn: Int) -> [String] {
        var result: [String] = []
        
        // 枚举小时和分钟
        for hour in 0..<12 {
            for minute in 0..<60 {
                // 计算二进制中1的个数
                if hour.nonzeroBitCount + minute.nonzeroBitCount == turnedOn {
                    // 格式化时间
                    let time = String(format: "%d:%02d", hour, minute)
                    result.append(time)
                }
            }
        }
        
        return result
    }
}

// 示例测试
let sol = Solution()
print(sol.readBinaryWatch(1))
print(sol.readBinaryWatch(2))
print(sol.readBinaryWatch(9))

代码解析

  1. hour.nonzeroBitCount:这是 Swift 的一个非常实用的属性,用来计算整数中 1 的数量,相当于 C++ 的 __builtin_popcount
  2. 我们遍历所有可能的时间组合,共 12 * 60 = 720 种。
  3. 只要当前时间的二进制亮灯数与输入的 turnedOn 相同,就把这个时间加入结果。
  4. String(format: "%d:%02d", hour, minute) 保证分钟是两位数格式,比如 "1:05"

整个逻辑非常直观,核心是利用二进制的位数统计来筛选。

示例测试及结果

示例 1

输入:

swift 复制代码
sol.readBinaryWatch(1)

输出:

复制代码
["0:01","0:02","0:04","0:08","0:16","0:32",
 "1:00","2:00","4:00","8:00"]

解释:

  • 当只有一个灯亮时,可能是某个分钟灯亮,也可能是某个小时灯亮。

示例 2

输入:

swift 复制代码
sol.readBinaryWatch(9)

输出:

txt 复制代码
[]

解释:

手表最多有 10 个灯,小时最多 4 位 + 分钟 6 位;如果亮 9 个灯,不可能构成合法时间。

示例 3

输入:

swift 复制代码
sol.readBinaryWatch(3)

输出示例:

txt 复制代码
["0:07", "0:11", "1:03", "2:05", "3:00", "4:06", "8:03", ...]

时间复杂度

  • 枚举所有小时(12 种)和分钟(60 种),总共 720 次循环。
  • 每次循环只做常数级别操作(位数统计 + 拼接字符串)。
    所以时间复杂度为 O(720) ,即 O(1) 常数级。

空间复杂度

只使用了一个结果数组,没有额外结构。

空间复杂度为 O(1)(不计输出结果)。

总结

这题是一个非常典型的"枚举 + 二进制位计数"问题。

虽然题目看起来和时间有关,但其实本质是一个组合问题:有 10 个灯,开了几个,就代表一个唯一的小时+分钟组合。

相关推荐
派大星爱吃猫4 小时前
顺序表算法题(LeetCode)
算法·leetcode·职场和发展
liu****4 小时前
8.list的模拟实现
linux·数据结构·c++·算法·list
地平线开发者5 小时前
征程 6 | 征程 6 工具链如何支持 Matmul/Conv 双 int16 输入量化?
算法·自动驾驶
ITKEY_5 小时前
ssh中neovim无法复制文本 clipboard
运维·ssh
程序员大雄学编程6 小时前
「深度学习笔记4」深度学习优化算法完全指南:从梯度下降到Adam的实战详解
笔记·深度学习·算法·机器学习
小O的算法实验室6 小时前
2022年ASOC SCI2区TOP,基于竞争与合作策略的金字塔粒子群算法PPSO,深度解析+性能实测,深度解析+性能实测
算法·论文复现·智能算法·智能算法改进
南莺莺6 小时前
邻接矩阵的基本操作
数据结构·算法··邻接矩阵
微波仿真7 小时前
实现多通道ADC多次测量取平均值,使用DMA
算法
余俊晖7 小时前
多模态文档理解视觉token剪枝思路
人工智能·算法·剪枝·多模态