近刷到个帖子:某大厂哥们说自己人生崩了——赚了1000多万买房踩雷亏了,孩子成绩全班倒数,媳妇天天抱怨,活得像线上事故现场,报警还得先写复盘。
我觉得他最大的问题不是亏钱,是把人生当版本迭代,啥都想一次上线成功。说真的,这种吐槽帖的好处就在这:发出来有人接话,顺便看看别人的bug,心态就没那么容易崩,至少你会发现——原来大家都在各自的坑里努力爬。
算法题 : 移除 9
我跟你说个笑话啊,上次面试一个小朋友,我随口一问:你会不会“移除 9”这道题? 他愣了一下,说:把 9 删了不就完了么? 我当时就知道,完了,这孩子估计只刷了题目标题,没刷题
所谓“移除 9”,就是这样的: 给你一个正整数 n,让你返回“第 n 个 十进制表示里不含数字 9 的正整数”。 比如: 1 → 1 8 → 8 9 → 10(因为 9 本人不能要,要跳过去)
你看着是不是有点像电梯没有 4 楼、14 楼那种感觉,对吧。
我当时在工位上拿纸一算,啊这,要是我傻乎乎从 1 开始数,遇到带 9 的跳过,一直数到第 n 个,代码大概长这样,特别费 CPU 那种:
PHP
functionnthNoNineBrutal(int $n): int{
$num = 0;
$cnt = 0;
while ($cnt < $n) {
$num++;
if (!containsNine($num)) {
$cnt++;
}
}
return $num;
}
functioncontainsNine(int $x): bool{
// 把数字拆开看有没有 9
while ($x > 0) {
if ($x % 10 == 9) {
returntrue;
}
$x = intdiv($x, 10);
}
returnfalse;
}echo nthNoNineBrutal(8), PHP_EOL; // 8
echo nthNoNineBrutal(9), PHP_EOL; // 10
这个写法面试的时候写出来,面试官一般会笑眯了眼,然后温柔地跟你说一句: “那如果 n 是 10^9 呢?” 然后你就会在本地把 CPU 烤熟,机器开始呼呼转风扇,结果还超时。
那这题正解是啥呢? 关键在于你要 换一个思路 :既然十进制里不能出现 9,那不如我们干脆 直接不用 9 这个数字 。
你想象下:
允许的数字只有 0~8,一共 9 个
每一位只能用这 9 个数字 听起来是不是很像: 把 n 看成一个 9 进制数,再把“9 进制的每一位”当成十进制的每一位输出 ?
举个小例子,你心里感受一下(别太较真手算,我就随便说下思路):
n 用 9 进制表示出来,比如是
abc(9)我们就直接输出十进制数字
abc因为 9 进制里每一位都在 0~8 之间,所以这个十进制数的每一位也都在 0~8,不可能有 9
这样自然就是“不含 9 的第 n 个数”了
所以这题本质就是一句话: 答案 = n 的 9 进制表示,把它当成十进制数读出来。
用 PHP 写就非常干净了,一点也不花里胡哨:
php
functionnthNoNine(int $n): int{
$res = 0;
$base = 1;
// 核心:把 n 看成 9 进制,然后“伪装”成十进制
while ($n > 0) {
$digit = $n % 9; // 取 9 进制当前位(0~8)
$res += $digit * $base; // 放到十进制对应位上
$base *= 10; // 十进制往高一位走
$n = intdiv($n, 9); // 9 进制右移一位
}
return $res;
}echo nthNoNine(1), PHP_EOL; // 1
echo nthNoNine(8), PHP_EOL; // 8
echo nthNoNine(9), PHP_EOL; // 10
echo nthNoNine(10), PHP_EOL; // 11
echo nthNoNine(100), PHP_EOL;
你仔细看一下这个循环,其实就是手写一个“9 进制 → 伪十进制”的转换过程:
digit = n % 9就是在取 9 进制的个位n = intdiv(n, 9)就是 9 进制整体右移一位base *= 10则是在十进制这边把位数往左挪
俩世界中间来回倒腾一下,题就做完了,时间复杂度是 O(log₉ n),面试官一般会点点头说一句“嗯,还行”。
这题有意思的地方就是: 刚开始你会直觉“把 9 删掉”,结果一算发现删不动; 最后你会发现真正好用的不是“删除”,而是 从一开始就假装 9 不存在 ,在一个根本没有 9 的计数系统里数数。
就跟写代码一样,有时候你拼命想怎么兜 bug,其实更好的办法,是一开始就别把那个坑挖出来。
行了,先这样,你可以把上面两个版本都敲一遍,体验一下一个是“CPU 烧烤版”,一个是“进制优雅版”。 下次面试再碰到“移除 9”,别再说“把 9 删了就完了”啊
特别声明:以上内容(如有图片或视频亦包括在内)为自媒体平台“网易号”用户上传并发布,本平台仅提供信息存储服务。
Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.