
本文介绍一种高效算法:给定一个正整数,统计其各位数字出现频次,其中数字 6 和 9 可互相替代(视为同一资源),每套数字集合含 0–9 各一个;目标是求出最少需要几套集合才能完整写出该数字。
本文介绍一种高效算法:给定一个正整数,统计其各位数字出现频次,其中数字 6 和 9 可互相替代(视为同一资源),每套数字集合含 0–9 各一个;目标是求出最少需要几套集合才能完整写出该数字。
在数字资源受限场景中(如物理数字贴纸、LED 显示模块或印刷模板),常需评估“书写某数字最少消耗多少套 0–9 全数字集”。关键约束在于:6 和 9 可通过旋转 180° 互换使用,即一个「6」可当「9」用,反之亦然——因此它们共享同一类资源池,而非独立占用。
核心思路是:
- 将输入数字转为字符串,统一将 '9' 替换为 '6'(或反之),使所有可互换数字归一化;
- 统计归一化后各数字的出现次数;
- 对数字 '6' 的计数执行向上取整除以 2(因一套集合仅提供一个 6/9 实体,却可服务两个角色);
- 最终结果 = 所有数字频次中的最大值——因为瓶颈由出现最频繁的数字决定。
以下是完整、健壮、已验证的 PHP 实现:
function countSetsRequired(string|int $num): int
{
// 强制转字符串并处理空输入
$str = trim((string)$num);
if ($str === '' || !ctype_digit($str)) {
throw new InvalidArgumentException('Input must be a non-empty positive integer string');
}
// 归一化:将所有 '9' 替换为 '6',便于统一计数
$normalized = str_replace('9', '6', $str);
$digits = str_split($normalized);
// 统计每个数字出现次数
$counts = array_count_values($digits);
// 特殊处理:6 和 9 共享资源,一套集合只含一个 6/9 实体
if (isset($counts['6'])) {
$counts['6'] = (int)ceil($counts['6'] / 2.0);
}
// 最大频次即所需最少集合数(其他数字均 ≤ 此值,可被覆盖)
return (int)max($counts);
}
// ✅ 测试用例验证
var_dump(countSetsRequired(10)); // → 1 ('1','0' 各1次)
var_dump(countSetsRequired(300)); // → 2 ('0' 出现2次)
var_dump(countSetsRequired(266)); // → 1 ('2','6','6' → 归一化为 '2','6','6' → 6频次=2 → ceil(2/2)=1)
var_dump(countSetsRequired(369)); // → 1 ('3','6','9' → 归一化为 '3','6','6' → 同上)
var_dump(countSetsRequired(5666)); // → 2 ('5','6','6','6' → 6频次=3 → ceil(3/2)=2)⚠️ 注意事项:
立即学习“PHP免费学习笔记(深入)”;
- 输入必须为合法非负整数(函数内置校验,抛出 InvalidArgumentException);
- 不支持科学计数法或带符号数字(如 -123 或 1e3),调用前请确保清洗;
- 时间复杂度为 O(n)(n 为数字位数),空间复杂度 O(1)(最多 10 个键);
- 若业务需扩展支持其他可互换对(如 1/l/I),建议将归一化逻辑抽离为配置化映射表。
该方案简洁、可读性强,且经在线沙箱 PHP Sandbox 验证通过。实际项目中可直接集成,并根据需要添加日志或缓存优化。











