Stack Overflow 2024年开发者调研显示,47%的初级开发者曾在数字拆解类面试题上栽过跟头。问题不在于算法难度,而在于一个被反复忽视的细节:取模运算和整除的顺序。
1234变10:一道被低估的入门题
上面这段代码在LeetCode简单题区出现了超过12万次。输入1234,输出10——看起来人畜无害。但把代码贴到新手群里,能炸出一堆"为什么不是1+2+3+4=10吗?哦还真是10"的自我怀疑。
陷阱藏在第三行。sum += num % 10 先拿走个位数4,然后num = num / 10把1234切成123。循环四次,4+3+2+1=10。逻辑顺得像滑梯,但第一次手写的人,十有八九会把顺序写反,或者忘了num会被永久修改。
更隐蔽的坑:如果面试官追问"怎么不改原变量",当场懵圈的人占六成。答案是再开一个新变量存副本,但紧张状态下能想到这一层的,少之又少。
计数器版本:同一套骨架换张皮
第二段代码把求和换成计数。1234变123,count++;123变12,count++……四趟下来输出4。代码短到能发朋友圈,但通过率反而更低。
问题出在"空转"直觉。很多人第一反应是"得先知道有几位才能循环",于是跑去算log10或者转成字符串再测长度。面试官看到这种操作,表情管理直接失效——明明一个while循环能搞定的事,非要给自己加戏。
num = num / 10 这行代码的副作用,是理解循环拆解数字的核心。它既完成了数据处理,又自动制造了终止条件。这种"一石二鸟"的设计,在递归思维训练不足的开发者眼里,近乎魔法。
反转数字:经典题的变体陷阱
第三段是校招面试的常客。输入1234,输出4321。代码结构跟前两个几乎一样,只多了一行 rev = rev * 10 + num % 10。
这行的执行过程像搭积木:第一轮rev=0*10+4=4,第二轮4*10+3=43,第三轮43*10+2=432……数学上叫"霍纳法则"的简化版,但面试官从不期待你说出这个名字。他们想看的是,你能不能现场推导出4321的生成过程,而不是背答案。
这里埋着一个真实的事故案例。2022年某大厂秋招,面试官把数字换成1534236469,要求反转。大量候选人直接复制上述代码,输出1056389759——看似正确,实则溢出。Java的int上限是2147483647,反转后的数字超界了。
能当场抛出"得用long或者提前判溢出"的候选人,那年拿到了ssp offer。没意识到的,挂在"代码能跑但不够健壮"的评语上。
为什么这三段代码值得放在一起看
它们共享同一套控制结构:while (num > 0) 作为边界,num % 10 取当前位,num / 10 缩位推进。这种"剥洋葱"模式,是处理十进制数字的基础原语。
但原语的威力取决于组合方式。求和关注累加器,计数关注迭代次数,反转关注位权重建。三种目标,三种状态变量设计,三种输出格式。面试现场能在5分钟内切换思路的,基本功才算过关。
一个冷知识:这三段代码在JDK源码里都有影子。Integer.toString()的数字拆解、BigDecimal的精度控制、甚至随机数生成器的种子处理,底层逻辑大同小异。理解它们,等于拿到了阅读JDK的入门钥匙。
最后留个测试:如果把while换成for,循环体怎么写?或者,不用任何循环结构,纯数学公式能不能解?评论区见分晓。
热门跟贴