*python3__leecode/0401.二进制手表

本文介绍了如何用Python解决LeetCode上的二进制手表问题。通过两种方法,遍历法和递归回溯法,找出所有可能的时间表示。题目要求根据点亮的LED数量,确定所有可能的小时和分钟组合,并确保时间格式正确。提供的代码详细展示了这两种解题思路。

一、刷题内容

原题链接

https://leetcode-cn.com/problems/binary-watch/

内容描述

  1. 二进制手表
    二进制手表顶部有 4 个 LED 代表 小时(0-11),底部的 6 个 LED 代表 分钟(0-59)。每个 LED 代表一个 0 或 1,最低位在右侧。

例如,下面的二进制手表读取 “3:25” 。
二进制手表
给你一个整数 turnedOn ,表示当前亮着的 LED 的数量,返回二进制手表可以表示的所有可能时间。你可以 按任意顺序返回答案。

小时不会以零开头:
例如,“01:00” 是无效的时间,正确的写法应该是 “1:00” 。
分钟必须由两位数组成,可能会以零开头:

例如,“10:2” 是无效的时间,正确的写法应该是 “10:02” 。

示例 1:
输入:turnedOn = 1
输出:[“0:01”,“0:02”,“0:04”,“0:08”,“0:16”,“0:32”,“1:00”,“2:00”,“4:00”,“8:00”]

示例 2:
输入:turnedOn = 9
输出:[]

解释:

0 <= turnedOn <= 10

二、解题方法

1.方法一:遍历法

逆向思维

class Solution:
    def readBinaryWatch(self, turnedOn: int) -> List[str]:
        ans = list()
        for h in range(12):
            for m in range(60):
                if bin(h).count("1") + bin(m).count("1") == turnedOn:
                    ans.append(f"{h}:{m:02d}")
        return ans

2.方法二:递归回溯法

递归结构
r(n)=r(n-1)+wr(n)=r(n−1)+w

ww 代表从 numsnums 中选出一个数字。

递归边界
if (n == step)

递归参数
nn:亮灯数量
stepstep:递归层数
resultresult:单次结果
result_allresult
a

ll:最终结果

class Solution(object):
    def __init__(self):
        self.result_all = None
        self.nums = [1, 2, 4, 8, 1, 2, 4, 8, 16, 32]
        self.visited = None
    
    def readBinaryWatch(self, num):
        """
        :type num: int
        :rtype: List[str]
        """
        self.result_all = []
        self.visited = [0 for _ in range(len(self.nums))]
        self.dfs(num, 0, 0)
        return self.result_all
    
    def dfs(self, num, step, start):
        if step == num:
            self.result_all.append(self.handle_date(self.visited))
            return
        for i in range(start, len(self.nums)):
            self.visited[i] = 1
            if not self.calc_sum(self.visited):
                self.visited[i] = 0
                continue
            self.dfs(num, step + 1, i + 1)
            self.visited[i] = 0
        return
            
    def calc_sum(self, visited):
        sum_h = 0
        sum_m = 0
        for i in range(len(visited)):
            if visited[i] == 0:
                continue
            if i < 4:
                sum_h += self.nums[i]
            else:
                sum_m += self.nums[i]
        return 0 <= sum_h <= 11 and 0 <= sum_m <= 59
    
    def handle_date(self, visited):
        sum_h = 0
        sum_m = 0
        for i in range(len(visited)):
            if visited[i] == 0:
                continue
            if i < 4:
                sum_h += self.nums[i]
            else:
                sum_m += self.nums[i]
        result = "" + str(sum_h) + ":"
        if sum_m < 10:
            result += "0" + str(sum_m)
        else:
            result += str(sum_m)
        return result
<think>我们正在处理一个常见的Python语法错误:`SyntaxError: leading zeros in decimal integer literals are not permitted; use an 0o prefix for octal integers`。根据引用[1][2][3][4][5],这个错误通常发生在整数前使用了不必要的零(例如:02、03、022等)。在Python中,整数不能以0开头(除了0本身),因为以0开头的数字会被解释为八进制数(但Python3中已不再支持这种写法,必须使用0o前缀表示八进制)。 ### 错误原因分析 1. **整数前导零**:在Python中,十进制整数不能以0开头(例如:02, 03, 022等)。例如: - `d1 = datetime.date(2022, 03, 22)` 中的`03`和`22`(如果写成022)都会导致错误[^1]。 - `conv_num= int(02xd)` 中的`02`也会导致同样的错误[^2]。 2. **历史背景**:在Python2中,以0开头的数字表示八进制数(例如:010表示十进制的8)。但在Python3中,这种写法已被废弃,要求使用`0o`前缀表示八进制(例如:`0o10`表示八进制的10,即十进制的8)[^4]。 3. **错误信息含义**:错误提示建议使用`0o`前缀表示八进制整数,但如果你确实想使用十进制整数,则应该删除前导零。 ### 解决方案 1. **删除前导零**:将整数前面的0去掉。例如: - 将`03`改为`3` - 将`022`改为`22` 修正后的代码示例(引用[1]中的代码): ```python # 错误代码 # d1 = datetime.date(2022, 03, 22) # 正确代码 d1 = datetime.date(2022, 3, 22) ``` 2. **特殊情况:需要保留前导零**(例如表示日期、时间时希望保持两位数): - 使用字符串代替整数,然后在需要时转换为整数(但注意在构造日期对象时,参数必须是整数,所以不能直接传字符串)。 - 或者,在输出时使用字符串格式化来添加前导零,而不是在整数本身加零。 例如,在构造日期对象时,月份和日必须是整数,不能带前导零。如果你需要输出两位数的日期,可以使用格式化字符串: ```python d1 = datetime.date(2022, 3, 22) # 输出时格式化为两位数的月和日 formatted_date = d1.strftime("%Y-%m-%d") # 结果为"2022-03-22" ``` 3. **如果确实需要八进制表示**:使用`0o`前缀,例如`0o10`表示八进制的10(即十进制的8)。但这种情况较少见。 ### 错误示例及修正 1. **引用[2]中的错误**: ```python conv_num = int(02xd) ``` 这里有两个问题:一是`02`这个整数前导零,二是整个表达式`02xd`不是一个有效的整数。如果`02xd`是一个字符串,应该用引号括起来,然后转换: ```python conv_num = int("02xd", 16) # 如果这是一个十六进制字符串,但这里包含&#39;x&#39;和&#39;d&#39;,可能不是有效的 ``` 但根据上下文,可能用户是想写一个十六进制数?十六进制数在Python中以`0x`开头,例如`0x2A`。所以这里可能是想写一个十六进制数,但写错了。正确的写法可能是: ```python conv_num = 0x2A # 表示十六进制的2A,即十进制的42 ``` 2. **引用[4]中的错误**: ```python >>> 02 >>> 3-02 >>> -022 ``` 修正: ```python >>> 2 >>> 3-2 >>> -22 ``` ### 总结 - 在Python中,整数不能以`0`开头(除了`0`本身)。 - 如果遇到此错误,检查代码中所有整数字面量,删除前导零。 - 如果需要保留前导零用于显示,则在输出时使用字符串格式化(如`str.format`或f-string)来实现。 - 如果需要使用八进制数,请使用`0o`前缀(例如:`0o10`表示十进制的8)。 ### 相关问题 1. 如何在Python中正确表示八进制和十六进制数? 2. 如何将整数格式化为固定宽度(前导补零)的字符串? 3. 为什么Python3不允许十进制整数使用前导零? 4. 在日期处理中,如何确保月份和日总是显示两位数?</think>### Python "leading zeros in decimal integer literals" 错误解决方案 #### 错误原因分析 这个错误发生在Python代码中使用了前导零的十进制整数(如 `02`、`03`、`022` 等)[^1][^2][^3][^4]。Python 3.x 版本禁止这种写法,因为: 1. 前导零在编程语言中传统上表示八进制数(如 `010` 表示十进制的8) 2. 容易引起混淆(`02` 是十进制2还是八进制2?) 3. Python 3 严格区分不同进制数的表示法[^4] #### 解决方案 ##### 1. 直接删除前导零(推荐) ```python # 错误代码 d1 = datetime.date(2022, 03, 22) # 错误点:03 # 修正后 d1 = datetime.date(2022, 3, 22) # 删除前导零 ``` ##### 2. 使用字符串格式化为带前导零的数字 当需要显示前导零时(如日期格式),使用字符串格式化: ```python # 错误代码 print(f"日期: {03}/{22}") # 错误点:03 # 修正后 print(f"日期: {3:02d}/{22:02d}") # 输出: 日期: 03/22 ``` ##### 3. 特殊场景:八进制数表示 如果需要表示八进制数,使用 `0o` 前缀: ```python # 错误代码 permission = 0755 # 错误写法 # 修正后(八进制表示) permission = 0o755 # 正确写法,等于十进制493 ``` #### 常见错误场景及修复 **场景1:日期时间处理** [^1] ```python # 错误代码 from datetime import datetime dt = datetime(2023, 08, 15) # 错误点:08 # 修复方案 dt = datetime(2023, 8, 15) # 删除前导零 ``` **场景2:固定宽度数字格式化** ```python # 错误代码 hour = 08 # 错误写法 # 修复方案 hour = 8 # 存储为整数 print(f"{hour:02d}") # 输出: 08(显示时格式化) ``` **场景3:版本号处理** ```python # 错误代码 version = (3, 09) # 错误点:09 # 修复方案 version = (3, 9) # 存储为整数元组 print(f"v{version[0]}.{version[1]:02d}") # 输出: v3.09 ``` #### 为什么Python禁止前导零? 1. **消除歧义**:明确区分十进制、八进制、二进制等不同进制 2. **兼容性**:与Python 2.x 的八进制表示法(如 `0755`)区分开 3. **代码清晰**:避免数字表示上的混淆[^4] #### 相关问题 1. 如何在Python中正确表示八进制和十六进制数?[^4] 2. 日期处理时如何保持月份/日的两位数格式?[^1] 3. Python 2 和 Python 3 在数字表示上的主要区别是什么? 4. 为什么`0o755`在Python中是合法写法而`0755`会导致错误? 5. 如何批量修复代码中的前导零错误?
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

百里 Jess

你的鼓励将是我创作的最大动力

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

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

打赏作者

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

抵扣说明:

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

余额充值