LeetCode-Go 题解精讲:1689. 拆分最少数量的十-二进制数(Deci-Binary Numbers)
【免费下载链接】LeetCode-Go✅ Solutions to LeetCode by Go, 100% test coverage, runtime beats 100% | LeetCode 题解项目地址: https://gitcode.com/GitHub_Trending/le/LeetCode-Go
本篇围绕 LeetCode-Go 仓库中第 1689 题「拆分最少数量的十-二进制数」的题解文档展开:先完整还原题目定义、示例与约束,再从数位角度给出"答案即字符串中的最大数字"的数学论证,最后结合仓库中的 Go 实现源码与配套测试,说明这一 O(n) 线性扫描解法如何落地、如何验证。读完后你将掌握这道题的完整证明思路、Go 实现的细节取舍,以及在本仓库中运行该题测试与覆盖率检查的方法。
一、题目描述:什么是十-二进制数(deci-binary)
原始题目(见 题目文档)的英文定义如下:
A decimal number is calleddeci-binaryif each of its digits is either
0or1without any leading zeros. For example,101and1100aredeci-binary, while112and3001are not.Given a string
nthat represents a positive decimal integer, returntheminimumnumber of positivedeci-binarynumbers needed so that they sum up ton*.
中文大意(继承自原文档的"题目大意"小节):如果一个十进制数字不含任何前导零,且每一位上的数字不是 0 就是 1,那么该数字就是一个"十-二进制数"。例如101和1100都是十-二进制数,而112和3001不是。给定一个表示正整数的十进制字符串n,返回使若干正十-二进制数之和恰好等于n所需的最少数目。
原文档给出了三个示例,完整保留如下:
示例 1
Input: n = "32" Output: 3 Explanation: 10 + 11 + 11 = 32示例 2
Input: n = "82734" Output: 8示例 3
Input: n = "27346209830709182346" Output: 9约束条件同样完整继承:
1 <= n.length <= 10^5n只由数字字符组成n不含前导零,且表示一个正整数
从约束可以看到,n的长度上限达到 10 万位,远超任何内置整数的表示范围——这也是题目要求以字符串而非整数作为入参的原因:解法必须做到"逐字符处理",而不是把n解析成数值后再运算。
二、核心洞察:答案就是n中的最大数字
原文档"解题思路"小节指出,这题想通之后"代码就 3 行"。其论证可以拆解为下界证明与可达性构造两部分,这里完整展开。
下界:为什么不能少于最大数字
设n的某一位上数字为d(例如n = "82734"的千位是 8)。任何一个十-二进制数在该位上的取值只能是0或1,且没有借位或进位跨数累加的机制——k 个十-二进制数相加时,某一位的和最多只比 k 多出进位贡献,但为了在该位最终得到d,这 k 个数在该位至少要贡献出d个 1(进位只会帮助低位,不会凭空让高位数字减少所需加数个数)。因此加数个数k必须满足k >= d。对所有数位取最大值,得到:
最少数目 >= max(n 的每一位数字)以示例 1 为例,"32"的最大数字是 3,所以答案至少为 3;10 + 11 + 11 = 32恰好 3 个,验证了取等成立。
可达性:为什么最大数字就一定够
取k = maxDigit。对n的每一位,若该位数字为d,就让这k个数中任意d个在该位取 1、其余k - d个在该位取 0。由于每一位上取 1 的个数恰好等于该位数字d,逐位相加(含正常十进制进位)必然还原出n本身,且每个构造出的数都不含前导零问题(千位上若d >= 1,取 1 的那个数自然以 1 开头;若最高位d = 0,这与"n 不含前导零"的约束矛盾,故最高位d >= 1)。原文档用n = 23423723举例:这是一个 8 位数,最大数字是 7,所以至少需要 7 个数累加得到n;这 7 个数的千位都为 1,其他数位按需求取 0 和 1——例如万位是 2,就让 7 个数中任意 2 个的万位为 1,其余 5 个为 0 即可。
综合两部分,得到题目核心结论:
minPartitions(n) = max( n 的每一位十进制数字 )这是一个与数值大小无关、只与数位字符相关的性质,示例 2 中"82734"的最大数字为 8、示例 3 中"27346209830709182346"的最大数字为 9,均与给定输出吻合。
三、Go 实现:一次线性扫描求最大数字
仓库中的解题源码位于 1689. Partitioning Into Minimum Number Of Deci-Binary Numbers.go,与题解文档中的代码完全一致:
package leetcode func minPartitions(n string) int { res := 0 for i := 0; i < len(n); i++ { if int(n[i]-'0') > res { res = int(n[i] - '0') } } return res }实现要点逐条说明:
- 逐字节扫描,不解析为数值。
n是字符串,n[i]直接取到第i个字节的 ASCII 码;n[i]-'0'把它换算成对应的数字0~9,再显式转为int。整个过程不产生大数运算,天然满足"长度可达 10^5"的约束。 - 原地维护最大值。
res从 0 开始(题目保证n是正整数,故最终结果至少为 1),每遇到比当前res大的数字就更新,等价于对 10 个候选数字值做一轮取 max。由于单字节数字值域只有0~9,也可以写成if n[i] > byte('0'+res)之类的比较技巧,但当前写法可读性最好。 - 复杂度:时间 O(n),仅一次遍历;空间 O(1),除返回值外只用了
res一个变量。对于"答案只取决于最大数字"这类问题,这已是理论下界——必须至少看一遍所有字符才能确认最大值,不存在渐近更快的做法。 - 边界情况:
n = "1"时循环一次,res更新为 1 后返回 1,符合"至少需要 1 个正十-二进制数"的语义;全 0 的情况被约束条件排除(n表示正整数且无前导零)。
从源码结构看,该文件只有单一函数、无任何辅助类型,函数名minPartitions与 LeetCode 官方签名一致,可直接提交。
四、测试验证:用仓库的测试框架跑一遍
同目录下的 1689. Partitioning Into Minimum Number Of Deci-Binary Numbers_test.go 遵循本仓库统一的测试组织方式:定义para1689(入参结构体,字段n string)与ans1689(期望答案结构体,字段one int),再在Test_Problem1689中构造用例切片并逐个打印实际输出:
qs := []question1689{ { para1689{"32"}, ans1689{3}, }, { para1689{"82734"}, ans1689{8}, }, }两个用例正好对应题目文档中的示例 1("32" -> 3)与示例 2("82734" -> 8)。值得注意的是,测试以fmt.Printf打印【input】/【output】供人工比对,而ans1689中的期望值目前仅作为参考数据存在;这与该仓库多数题解测试的风格一致——把每题的核心示例固化为可重跑的最小回归集。
本仓库对全部题解包统一采用gotest.sh生成覆盖率文件,其内容很简单:
go test -covermode=atomic -coverprofile=coverage.txt ./leetcode/...也就是说,对第 1689 题所在包运行测试时,它与整个leetcode/...目录下的题解一起被编译、执行并统计覆盖率(结果写入 coverage.txt)。单独验证本题时,可以直接执行:
go test -v ./leetcode/1689.Partitioning-Into-Minimum-Number-Of-Deci-Binary-Numbers/由于包内仅含minPartitions一个被测函数,测试输出中【output】:3与【output】:8两个值即对应示例 1、示例 2 的判定;示例 3 的长字符串"27346209830709182346"期望输出 9,可手动调用minPartitions快速核对,其最大数字恰为 9,与结论一致。
五、小结
- 数学结论:把
n拆成最少数目的十-二进制数之和,答案就是n各位数字中的最大值——下界来自"每一位至多由每个加数贡献 1",上界由"按位分配 1 的个数"的构造法给出。 - 工程实现:一次 O(n) 线性扫描、O(1) 额外空间,用
n[i]-'0'完成字符到数字的换算,天然兼容 10^5 长度的超长数字串。 - 验证方式:仓库内以统一的
para1689/ans1689结构组织用例,覆盖题目前两个官方示例,并通过 gotest.sh 与其余题解一起纳入 100% 覆盖率的测试体系。
这道题的价值在于展示了"把数值问题翻译成数位问题"的视角:一旦意识到答案只与数位字符相关,复杂的大数处理问题就退化为一次字符扫描,这也是 LeetCode-Go 中多数字符串类题解"极简而正确"风格的典型代表。
【免费下载链接】LeetCode-Go✅ Solutions to LeetCode by Go, 100% test coverage, runtime beats 100% | LeetCode 题解项目地址: https://gitcode.com/GitHub_Trending/le/LeetCode-Go
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考