尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

剑指 Offer 64 题解:不借助循环与条件判断,用逻辑短路实现 1 + 2 + … + n

剑指 Offer 64 题解:不借助循环与条件判断,用逻辑短路实现 1 + 2 + … + n 剑指 Offer 64 题解不借助循环与条件判断用逻辑短路实现 1 2 … n【免费下载链接】LeetCode-Book《剑指 Offer》《图解算法数据结构》《Krahets 笔面试精选 88 题》Python, Java, C 解题代码项目地址: https://gitcode.com/GitHub_Trending/le/LeetCode-Book本篇基于 LeetCode-Book 仓库 剑指 Offer 题解文档详解「剑指 Offer 64. 求 1 2 … n」这道经典脑筋急转弯式算法题如何在禁用乘除法、禁用 for/while 循环、禁用 if-else 与三目运算符的苛刻限制下利用逻辑运算符的短路特性把递归作为循环的替身完成累加计算。读完后你将掌握短路求值short-circuit evaluation在 Java、Python、C 三种语言中的行为差异并能复现仓库中的可运行解法。题目与限制条件题目要求计算sum(1 2 … n)但对实现方式做了多重禁止不能使用乘除法不能使用for、while等循环语句不能使用if-else、三目运算符等条件判断语句。约束叠加后常规思路全部失效这道题本质上是在考察对语言级求值机制尤其是逻辑短路的理解深度。本文档给出的核心方法是用排除法一步步排除常规方案最终导向「短路效应 递归」的组合拳。排除法三种常规方案为何全部被禁方法一平均计算被乘除法禁令排除最直觉的公式是高斯求和(1 n) * n / 2一步到位但必须使用乘除法直接违反题目限制不可取。public int sumNums(int n) { return (1 n) * n / 2; }def sumNums(n): return (1 n) * n // 2int sumNums(int n) { return (1 n) * n / 2; }方法二迭代累加被循环禁令排除退而求其次可以逐项累加但循环必须依赖while或for同样被排除public int sumNums(int n) { int res 0; for (int i 1; i n; i) res i; return res; }def sumNums(n): res 0 for i in range(1, n 1): res i return resint sumNums(int n) { int res 0; for (int i 1; i n; i) res i; return res; }方法三递归被条件判断禁令排除再进一步可以用递归模拟累加但标准的递归终止条件必须写if依然不可取public int sumNums(int n) { if (n 1) return 1; n sumNums(n - 1); return n; }def sumNums(n): if n 1: return 1 n sumNums(n - 1) return nint sumNums(int n) { if (n 1) return 1; n sumNums(n - 1); return n; }关键问题由此浮出水面除了if和switch这类判断语句还有没有其他机制可以终止递归答案正是短路效应。核心原理逻辑运算符的短路效应常见的逻辑运算符有三种「与」「或||」「非!」。它们有一个重要的短路short-circuit特性if (A B) // 若 A 为 false则 B 的判断不会执行即短路直接判定 A B 为 false if (A || B) // 若 A 为 true则 B 的判断不会执行即短路直接判定 A || B 为 true对于运算符左侧表达式一旦为false右侧表达式根本不会被求值。把这个特性反过来用——让左侧表达式充当递归的终止判断n 1 sumNums(n - 1) // 当 n 1 时 n 1 不成立此时发生“短路”终止后续递归当n 1为true时继续求值右侧的sumNums(n - 1)递归推进当n 1时左侧为false发生短路sumNums(0)永远不会被调用递归自然终止。这样就把if (n 1) return;这一句判断等价地改写成了逻辑表达式完美绕开了条件语句禁令。最终解法三语言实现把短路表达式嵌入累加逻辑即可得到最终答案。原文档给出的实现要点有 3 条需要注意Java 中为构成完整语句需要引入一个辅助布尔变量x接收表达式结果否则编译报错Java 中开启递归的部分需改写为sumNums(n - 1) 0让整个右半部分作为一个布尔量参与运算否则会报错用成员变量res记录累加结果Java 也有不借助res的简洁写法。解法一借助成员变量 res 累加class Solution { int res 0; public int sumNums(int n) { boolean x n 1 sumNums(n - 1) 0; res n; return res; } }执行顺序先短路判断并触发递归递归在res n之前完成更深层的累加再把当前n加入res。仓库中的 Java 解法一源码 与上述完全一致并附带n 3的测试驱动期望输出6可直接用 JDK 编译运行验证。对应的 Python 版本利用了and表达式同样具备短路求值特性且 Python 中表达式可直接作为语句无需辅助变量class Solution: def __init__(self): self.res 0 def sumNums(self, n: int) - int: n 1 and self.sumNums(n - 1) self.res n return self.res仓库中的 Python 解法源码 同样内置了n 3的测试用例与驱动代码可直接python3 sfo_64_solve_1_2___n_s1.py运行。C 版本中是原生短路运算符表达式求值结果可以直接丢弃编译器会给出未使用值的提示但不影响运行写法最为干净class Solution { public: int sumNums(int n) { n 1 (n sumNums(n - 1)); return n; } };对应源码见 C 解法头文件依赖 include/include.hpp。解法二Java 无辅助变量写法Java 还有第二栏的简洁写法把累加动作直接嵌入短路表达式内部完全不借助resclass Solution { public int sumNums(int n) { boolean x n 1 (n sumNums(n - 1)) 0; return n; } }原理右侧(n sumNums(n - 1))把递归返回值写回参数n本身Java 形参按值传递修改只影响本帧的n随后 0将其转换为布尔量参与运算x只是满足语句语法的载体。仓库中的 Java 解法二源码 采用同样实现并带有n 3的验证入口。注意解法二的技巧依赖于「把返回值累加回形参」这一副作用。如果递归深度过大n可能溢出且该写法把语义压缩进单行表达式可读性较差工程实践中更推荐解法一。递归执行过程走查以sumNums(3)为例按解法一res成员变量版本推演执行过程sumNums(3)3 1成立先递归调用sumNums(2)sumNums(2)2 1成立先递归调用sumNums(1)sumNums(1)1 1为false短路不再递归避免了sumNums(0)乃至负数的无意义调用执行res 1返回res 1回到sumNums(2)执行res 2res 3回到sumNums(3)执行res 3res 6最终返回6。递归的「展开阶段」由短路表达式驱动而累加动作发生在「回溯阶段」——每一帧返回前把自己的n记入res最终得到1 2 3 6与仓库中各语言测试驱动的输出一致。复杂度分析时间复杂度 O(n)计算n (n-1) … 2 1需要开启n层递归调用空间复杂度 O(n)递归深度达到n调用栈占用 O(n) 的额外空间。从源码结构看三语言解法的测试用例均取n 3这类小输入由于递归深度等于n当n很大时例如接近 Java 默认栈能容纳的调用层数存在栈溢出StackOverflowError的风险这是该解法以空间换语法的固有代价。小结方案核心手段被排除/可用的原因平均计算(1n)*n/2数学公式使用乘除法违反限制迭代累加for/while循环语句使用循环违反限制标准递归 if终止条件判断使用if违反限制短路 递归最终解法短路求值仅用逻辑表达式通过所有限制本题的价值不在于「求和」本身而在于演示了一条通用的规避技巧当语言禁止某种语法结构时可以寻找具有等价控制流副作用的语言级机制来替代——条件判断可以被逻辑短路替代循环可以被递归替代。仓库中sfo_64_solve_1_2___n_s1、sfo_64_solve_1_2___n_s2两套 Java 实现分别展示了「辅助变量累加」与「形参回写」两种落地风格配合 Python 与 C 版本为三种语言下短路语义的细微差异是否需要辅助语句、表达式能否作为独立语句、结果值是否可丢弃提供了可直接编译运行的对照素材。【免费下载链接】LeetCode-Book《剑指 Offer》《图解算法数据结构》《Krahets 笔面试精选 88 题》Python, Java, C 解题代码项目地址: https://gitcode.com/GitHub_Trending/le/LeetCode-Book创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表