1. 问题背景与题目解析
LeetCode 1689题"十-二进制数的最少数目"乍看之下像是一道常规的数学题,但实际考察的是对问题本质的洞察力。题目要求我们找出表示给定十进制数n所需的最少十-二进制数个数。所谓十-二进制数,是指每一位只能是0或1的十进制数,比如1、10、11、100等都是合法的十-二进制数。
我第一次看到这个题目时,下意识地开始思考如何拆分数字、如何进行组合优化。但经过仔细分析后发现,这其实是一个典型的"脑筋急转弯"类问题,关键在于发现隐藏的数学规律,而不是使用复杂的算法。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 十-二进制数的数学特性
要理解这道题的解法,首先需要明确十-二进制数的几个关键特性:
- 每个十-二进制数的每一位只能是0或1
- 十-二进制数的数值大小不受二进制转换规则限制(即"10"表示十,而不是二)
- 多个十-二进制数相加时,各位独立相加,不会产生进位影响
这些特性决定了我们可以将原数的每一位单独考虑。例如,数字32可以分解为11+11+10,共3个十-二进制数。但有没有更优的分解方式呢?
3. 关键突破:发现最大数字规律
经过多次尝试不同数字的分解后,我注意到一个关键现象:所需十-二进制数的最少数目实际上等于原数字中最大的那个数字。比如:
- 数字32:最大数字是3 → 需要3个十-二进制数(11+11+10)
- 数字82734:最大数字是8 → 需要8个十-二进制数
- 数字5:最大数字是5 → 需要5个1相加
这个发现看似简单,但却是解决问题的核心。为什么这个规律成立?因为每个十-二进制数在同一数位上最多贡献1,所以对于数字d,至少需要d个十-二进制数才能凑够这个数字。
4. 算法实现:一次遍历解决方案
基于上述发现,我们可以设计出极其高效的算法:
- 将输入数字n作为字符串处理(避免数字转换的开销)
- 遍历字符串的每一个字符(即每一位数字)
- 记录遇到的最大数字
- 最终的最大数字就是答案
这个算法的时间复杂度是O(L),其中L是数字的位数,空间复杂度是O(1),因为只需要常数空间存储最大值。
以下是Python的实现代码示例:
python复制def minPartitions(n: str) -> int:
return int(max(n))
令人惊讶
