在这里插入图片描述
在这里插入图片描述

摘要

这道题其实是一个非常典型的组合枚举问题。我们有 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:

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

输入:

sol.readBinaryWatch(1)

输出:

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

解释:

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

示例 2

输入:

sol.readBinaryWatch(9)

输出:

[]

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

示例 3

输入:

sol.readBinaryWatch(3)

输出示例:

["0:07", "0:11", "1:03", "2:05", "3:00", "4:06", "8:03", ...]

时间复杂度

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

空间复杂度

只使用了一个结果数组,没有额外结构。
空间复杂度为 O(1)(不计输出结果)。

总结

这题是一个非常典型的“枚举 + 二进制位计数”问题。
虽然题目看起来和时间有关,但其实本质是一个组合问题:有 10 个灯,开了几个,就代表一个唯一的小时+分钟组合。

Logo

加入「COC·上海城市开发者社区」,成就更好的自己!

更多推荐