做推送的网站有哪些,开发软件价格,个人单页网站模板,在线做动漫图片视频在线观看网站力扣热题100实战 | 第9期#xff1a;回文数——从字符串到整数的双重视角前言一、题目#xff1a;什么是回文数#xff1f;关键点解读二、解法一#xff1a;字符串法#xff08;最简单直观#xff09;核心思想代码实现复杂度分析这段代码的优点和问题三、解法二#xff…力扣热题100实战 | 第9期回文数——从字符串到整数的双重视角前言一、题目什么是回文数关键点解读二、解法一字符串法最简单直观核心思想代码实现复杂度分析这段代码的优点和问题三、解法二整数反转法进阶思路核心思想代码实现图解流程复杂度分析这段代码的问题解决溢出加判断四、解法三反转一半最优解核心思想为什么只反转一半就够了算法步骤图解流程代码实现复杂度分析为什么这是最优解五、细节剖析面试官真正关心的问题Q1为什么负数不是回文数Q2为什么末尾是0的数除了0本身不是回文数Q3反转一半解法的循环条件为什么是 x reversedQ4反转一半解法中为什么最后要比较 x reversed / 10Q5反转一半解法真的不会溢出吗六、面试官追问进阶版追问1如果要求用递归实现怎么写追问2如果数字是以字符串形式给出的超长整数比如100位怎么判断回文追问3如何找到下一个回文数追问4如果要求判断一个数是否为回文数但不允许使用除法和取模运算怎么实现七、实际开发这道题到底有什么用场景1身份证号校验场景2对称密码学场景3数据清洗中的模式识别场景4面试热身题八、总结从一道题到一类题附录思考题回文数的魅力在于它是一座桥梁——连接了字符串处理和整数运算两个世界。而你今天要学的就是在这两种视角之间自如切换。前言你好我是礼拜天没时间。前八期我们系统学习了哈希表、链表操作、滑动窗口、二分查找、动态规划、双指针等多种算法思想。这一期我们稍微放慢脚步来解一道看似简单却暗藏玄机的题目——回文数LeetCode 第9题。这道题在力扣上被标记为简单但它的简单只是表象。真正的高手能从这道题中看到边界处理的重要性、整数运算的细节以及算法优化的思路。我第一次做这道题时用字符串反转一行代码就解决了得意洋洋地提交——然后被面试官追问“如果不转换成字符串呢”“整数反转时溢出了怎么办”能只反转一半吗这些问题让我意识到简单的题目往往藏着最深的细节。今天我希望能带你从多个角度审视这道题真正吃透它。一、题目什么是回文数先看题目描述LeetCode 第9题给你一个整数x如果x是一个回文整数返回true否则返回false。回文数是指正序从左向右和倒序从右向左读都是一样的整数。进阶你能不将整数转为字符串来解决这个问题吗示例 1输入x 121 输出true 解释121 从左向右读是 121从右向左读也是 121示例 2输入x -121 输出false 解释-121 从左向右读是 -121从右向左读是 121-不一样示例 3输入x 10 输出false 解释10 从左向右读是 10从右向左读是 01不一样示例 4输入x -101 输出false关键点解读负数的处理所有负数都不可能是回文数因为负号的存在破坏了对称性示例2。末尾为0的情况如果数字末尾有0除了0本身其他都不可能是回文数。比如10反转后是01不相等 。进阶要求题目特别提示不将整数转为字符串这是在考察我们对整数运算的掌握。数据范围32位有符号整数范围是[-2³¹, 2³¹-1]约 ±21亿。二、解法一字符串法最简单直观当我第一次看到这道题我的第一反应是转换成字符串然后双指针判断。核心思想把整数转成字符串然后用两个指针分别指向字符串的首尾逐个比较字符是否相等 。代码实现classSolution{publicbooleanisPalindrome(intx){// 负数直接返回falseif(x0){returnfalse;}// 转换为字符串StringsInteger.toString(x);intleft0;intrights.length()-1;// 双指针比较while(leftright){if(s.charAt(left)!s.charAt(right)){returnfalse;}left;right--;}returntrue;}}复杂度分析时间复杂度O(n) —— 需要遍历字符串的一半n是数字的位数空间复杂度O(n) —— 需要存储转换后的字符串这段代码的优点和问题✅优点代码简单直观容易理解适合快速解题。❌问题空间浪费需要额外的字符串空间不符合进阶要求题目明确希望我们不转字符串面试减分面试官会追问更优解法三、解法二整数反转法进阶思路如果不转字符串那就要直接操作整数。一个很自然的想法是把整数反转然后和原数比较。核心思想将整数x完全反转得到reversed如果reversed x则是回文数代码实现classSolution{publicbooleanisPalindrome(intx){// 负数和末尾为0且非0的数不是回文数if(x0||(x%100x!0)){returnfalse;}intreversed0;intoriginalx;while(x0){intdigitx%10;// 取最后一位reversedreversed*10digit;// 拼接到反转数后x/10;// 去掉最后一位}returnoriginalreversed;}}图解流程以x 12321为例步骤xdigitreversed说明初始12321-0第1步123210×1011取出1反转得1第2步12321×10212取出2反转得12第3步12312×103123取出3反转得123第4步12123×1021232取出2反转得1232第5步011232×10112321取出1反转得12321最终original 12321reversed 12321相等返回true。复杂度分析时间复杂度O(n) —— 需要遍历数字的每一位n是位数空间复杂度O(1) —— 只用了常数变量这段代码的问题看起来完美但有一个隐藏的陷阱整数溢出。当x接近Integer.MAX_VALUE时反转后的数可能超出32位整数的范围。比如x 2147483647反转后是7463847412这已经超过2³¹-1了。虽然题目输入保证了x本身在范围内但反转后的数不一定。我们需要处理这个溢出问题。解决溢出加判断while(x0){intdigitx%10;// 检查是否溢出if(reversedInteger.MAX_VALUE/10||(reversedInteger.MAX_VALUE/10digit7)){returnfalse;// 溢出不可能是回文数}reversedreversed*10digit;x/10;}四、解法三反转一半最优解上面的解法虽然可行但反转整个数字有点浪费——我们其实只需要比较一半就够了 。核心思想只反转数字的后半部分比较前半部分和反转后的后半部分如果相等或者相差一位就是回文数为什么只反转一半就够了因为回文数是对称的前半部分应该等于后半部分的反转。算法步骤处理边界情况负数直接返回false末尾为0且非0的数返回false初始化reversed 0当x reversed时循环说明还没处理到一半取x的最后一位加到reversed后面x去掉最后一位循环结束后如果数字长度是偶数x reversed如果数字长度是奇数x reversed / 10去掉中间那位图解流程以x 12321为例步骤xreversedx reversed?操作初始123210是第1步12321是取1加到reversed第2步12312是取2加到reversed第3步12123否停止此时x 12reversed 123x reversed/1012 12返回true。以x 1221为例步骤xreversedx reversed?操作初始12210是第1步1221是取1加到reversed第2步1212否取2加到reversed后停止此时x 12reversed 12x reversed返回true。代码实现classSolution{publicbooleanisPalindrome(intx){// 负数和末尾为0且非0的数不是回文数if(x0||(x%100x!0)){returnfalse;}intreversed0;// 反转一半while(xreversed){reversedreversed*10x%10;x/10;}// 偶数长度x reversed// 奇数长度x reversed / 10returnxreversed||xreversed/10;}}复杂度分析时间复杂度O(n/2) ≈ O(n) —— 只反转一半数字空间复杂度O(1) —— 只用了常数变量为什么这是最优解避免溢出只反转一半不会出现溢出问题省时省力比反转整个数字少了一半操作符合进阶要求纯整数运算无字符串转换面试加分展示了深度思考和优化能力五、细节剖析面试官真正关心的问题Q1为什么负数不是回文数答案因为负号的存在破坏了对称性。比如-121从左向右读是-121从右向左读是121-显然不等。题目定义的就是整数不包括符号 。Q2为什么末尾是0的数除了0本身不是回文数答案如果一个数末尾是0比如10、120反转后的数会以0开头但整数不能以0开头除了0本身。所以这些数不可能是回文数。例如10反转后是01在整数中就是1不相等。120反转后是21也不相等。Q3反转一半解法的循环条件为什么是x reversed答案这是关键点。当x reversed时说明我们已经处理到数字的中线了如果数字长度是偶数此时x和reversed应该相等如果数字长度是奇数此时x应该比reversed少一位中间的那位在reversed里Q4反转一半解法中为什么最后要比较x reversed / 10答案这是为了处理奇数长度的情况。比如12321当循环结束时x12reversed123中间的数字3被放在了reversed的最后一位。我们去掉这一位比较x和reversed/10即12是否相等 。Q5反转一半解法真的不会溢出吗答案不会。因为我们只反转了一半reversed的大小最多和原数的一半相当永远不会超过Integer.MAX_VALUE。六、面试官追问进阶版追问1如果要求用递归实现怎么写思路可以用递归反转数字但需要注意递归深度和尾递归优化。classSolution{publicbooleanisPalindrome(intx){if(x0)returnfalse;returnxreverse(x,0);}privateintreverse(intx,intrev){if(x0)returnrev;returnreverse(x/10,rev*10x%10);}}但这种方法会反转整个数字同样有溢出风险且递归深度受限于位数最多10层还好。追问2如果数字是以字符串形式给出的超长整数比如100位怎么判断回文思路那就只能用字符串双指针了。因为整数类型无法存储这么大的数。publicbooleanisPalindrome(Strings){intleft0,rights.length()-1;while(leftright){if(s.charAt(left)!s.charAt(right)){returnfalse;}left;right--;}returntrue;}追问3如何找到下一个回文数思路这是一个扩展问题。给定一个数找比它大的最小回文数。需要分情况讨论如果数本身就是回文直接加1再处理否则把前半部分复制到后半部分然后判断是否大于原数追问4如果要求判断一个数是否为回文数但不允许使用除法和取模运算怎么实现思路可以用字符串法或者用数学方法——用循环不断除以10用减法代替取模不现实。所以字符串法是最合适的。七、实际开发这道题到底有什么用很多读者会问“回文数判断实际工作中哪用得到”其实它的思想无处不在场景1身份证号校验在某些业务场景中需要校验用户输入的身份证号是否可能是有效的。虽然身份证不是回文但对称性校验的思想可以用于其他格式验证。场景2对称密码学一些简单的加密算法利用对称性设计判断字符串是否对称是基础操作。场景3数据清洗中的模式识别在数据清洗中需要识别特定模式的字符串比如回文日期20211202等。场景4面试热身题这道题常作为面试的热身题考察面试者的代码风格、边界处理能力和优化意识。八、总结从一道题到一类题回顾一下我们从回文数学到了什么维度收获算法思维字符串法 → 完整反转法 → 反转一半法理解逐步优化的过程代码技巧边界条件处理、整数反转、溢出判断、奇偶统一处理复杂度分析时间O(n)、空间从O(n)优化到O(1)面试要点为什么负数不行末尾0的处理反转一半的条件工程关联格式校验、模式识别、面试热身力扣热题100的第九题不是为了难住你而是为了告诉你简单的题目也能挖出深坑基础的知识也能体现水平。真正的高手能在平凡处见真章。下一期预告《正则表达式匹配》——动态规划的巅峰之作附录思考题看完这篇文章你可以试着回答如果要求判断一个字符串是否为回文串忽略大小写和非字母数字字符代码怎么改如果要求找出一个整数数组中的所有回文数最优算法是什么你能用这道题的思路去解 LeetCode 234回文链表吗欢迎在评论区留下你的思考