2026/5/14 9:41:07
网站建设
项目流程
小网站文案,专业模板建站哪家好,网站设计自学,品牌网上和实体店质量一样吗1. 题目描述#xff1a;求“数根”问题
题目链接
给定正整数 nnn#xff08;如 38#xff09;#xff0c;不断将其各位数字相加#xff0c;直到结果为一位数。
38 → 3811 → 112 → 输出 2这道题可用循环轻松解决#xff0c;但我们的目标是#xff1a;用递归来写求“数根”问题题目链接给定正整数n nn如 38不断将其各位数字相加直到结果为一位数。38 → 3811 → 112 → 输出 2这道题可用循环轻松解决但我们的目标是用递归来写并从中提炼通用方法。2. 什么样的问题适合用递归不是所有问题都值得用递归。真正适合递归的问题通常具备以下三个特征特征 1自相似性Self-similarity问题的结构在不同规模下“看起来一样”。数根f(n) f(各位和)→ 问题形式完全相同阶乘n! n × (n-1)!一句话判断如果你能用“……的……”来描述问题如 n 的数根 n 的各位数字之和的数根。那它很可能适合递归。特征 2存在明确的最小情况Base Case必须有无需递归就能直接回答的情形。数根n 10→ 直接返回n阶乘0! 1没有基线条件 → 无限递归 → 栈溢出特征 3每次递归让问题变小并趋近基线参数必须朝着终止条件收敛。n → sum_of_digits(n)38 → 11 → 2n → n-1阶乘❌ 如果递归后问题没变小如f(n) f(n)就会死循环。3. 如何写出正确的递归程序——三步心法掌握了“识别”接下来是“构造”。我们用递归三步心法来写“数根”第一步写出基线条件Base Case问什么情况下我不需要再递归对数根→ 如果n 10它本身就是答案if(n10){returnn;// 出口}技巧先写这一行避免忘记出口。第二步定义递归关系Recursive Step问当前问题能否转化为一个“更小”的同类问题对数根→ 先算各位和x然后求x的数根returncalc(x);// 问题规模缩小关键心态不要试图脑内展开所有调用只需相信calc(x)能正确返回x的数根。你只负责当前层。第三步实现“缩小问题”的工具有时需要一小段逻辑生成子问题输入。对数根计算各位和intx0;while(n){xn%10;n/10;}这段代码不属于递归思想本身只是辅助。可内联也可拆成独立函数。完整代码三步合一#includebits/stdc.husingnamespacestd;intcalc(intn){// 第一步基线条件if(n10)returnn;// 第三步工具——计算各位和intx0;while(n){xn%10;n/10;}// 第二步递归调用问题变小returncalc(x);}intmain(){intn;cinn;coutcalc(n)endl;return0;}安全递归深度 ≤ 3正确符合数学定义清晰三步结构分明4. 避坑指南错误表现解决方案忘记基线条件栈溢出先写if (base) return ...问题没变小无限递归检查参数是否真的缩小如n → x n过度复杂化逻辑混乱只专注当前层判断 → 缩小 → 调用口诀“先写出口再缩问题相信子问题能搞定。”5. 总结适合递归的问题 自相似 有出口 能缩小写递归的三步心法1️⃣ 写基线条件先保命2️⃣ 定义递归关系信子问题3️⃣ 实现缩小工具辅助逻辑不要怕递归——它只是“让问题自己解决自己”的思维方式。