面试必考字符串算法:3类高频题+4套可直接复制代码,吃透轻松拿下前端算法手撕题
前言
前端面试手撕算法,字符串题出现频率稳居前3。
很多同学只会用split/reverse简单API写法,遇到最多删除一个字符判断回文这类变形题直接卡壳。
读完本文你能收获:
JS字符串底层包装类、toString、call原理底层讲解
基础回文字符串两套实现:API简化版、双指针最优版
高频变形题:最多删1字符判断回文完整可运行代码
字符串反转标准面试写法,避开底层踩坑点
面试手写题答题思路模板,直接背
全文代码均可复制运行,无冗余逻辑,适配面试官现场手写场景。
一、基础前置:JS字符串底层必懂知识点(面试常追问)
1. 简单字符串没有reverse方法,数组才有reverse
JS原始字符串属于基本数据类型,不存在数组反转API。
标准反转字符串三步流程:
split(''):字符串转数组reverse():数组原地反转join(''):数组拼接回字符串
示例代码:
// 字符串反转标准写法letstr='hello'letres=str.split('').reverse().join('')console.log(res)// 'olleh'踩坑提醒:
如果字符串带空格,split(" ")会按空格分割,反转会错乱,无特殊分隔符统一用split('')。
2. toString、JSON.stringify 区分对象序列化
obj.toString():默认返回[object Object],只能区分对象类型,无法输出对象内容JSON.stringify(obj):真正序列化对象,输出完整JSON字符串
示例:
leto={a:1,b:2}console.log(o.toString())// "[object Object]"console.log(JSON.stringify(o))// "{"a":1,"b":2}"// 数组toString会自动拼接逗号console.log([1,2,3].toString())// "1,2,3"3. call改变函数this指向 + 包装类底层原理
call使用场景
函数本质是对象,call可以借用函数,修改函数执行时this指向。
leto={name:"胡老板",say:function(){console.log("我是"+this.name)}}letobj={name:"张老板"}o.say()// 我是胡老板o.say.call(obj)// 我是张老板,this指向obj包装类底层(面试官高频追问)
原始字符串本身是简单类型,理论上不能调用.length、.split等对象方法。
JS底层会自动做包装类转换:
执行str.length时,临时new String(str)生成字符串实例,调用属性方法,执行完立刻销毁实例,变回原始字符串。
对外完全无感知,统一面向对象写法,降低开发成本。
二、基础算法1:判断回文字符串(正反读取一致)
场景说明
面试第一题高频题:判断输入字符串是否为回文,如racecar是回文,hello不是。
方案1:极简API写法(适合快速实现)
逻辑:反转字符串和原字符串对比,相等即为回文
functionisPalindrome(s){returns.split('').reverse().join('')===s;}// 测试用例console.log(isPalindrome("racecar"))// trueconsole.log(isPalindrome("hello"))// falseconsole.log(isPalindrome("a"))// true方案2:双指针对称解法(最优解,空间O(1),面试官更爱)
思路:只遍历一半字符串,首尾对称位置一一对比,不额外生成数组,节省内存
functionisPalindrome2(s){letlen=s.length;for(leti=0;i<len/2;i++){// 左侧i,右侧对称位置 len-1-iif(s[i]!==s[len-1-i]){returnfalse;}}returntrue;}// 测试用例console.log(isPalindrome2("racecar"))// trueconsole.log(isPalindrome2("hello"))// falseconsole.log(isPalindrome2("a"))// true踩坑提醒
API解法会额外开辟数组空间,超长字符串性能不如双指针;
题目如果包含大小写、数字、符号,需要提前过滤字符,本文基础题默认纯英文无干扰字符。
三、进阶变形题:最多删除1个字符,判断能否构成回文(大厂高频)
题目需求
给定非空字符串,允许最多删除1个字符,判断剩余字符是否为回文。
示例:abca删除b/a都能形成回文,返回true;abc无论删哪个都不行,返回false。
解题思路
双指针首尾同步匹配,遇到不相等字符时出现分支;
两种容错方案:删除左指针字符、删除右指针字符;
封装子函数,校验截取区间是否纯回文,满足任一方案即返回true。
完整可运行代码:
functionvalidPalidrome(s){constlen=s.length;leti=0,j=len-1;// 首尾相等则双向靠近while(i<j&&s[i]===s[j]){i++;j--;}// 校验区间[st,ed]是否严格回文functionisPalindrome(st,ed){while(st<ed){if(s[st]!==s[ed]){returnfalse;}st++;ed--;}returntrue;}// 分支1:删除左字符 i+1if(isPalindrome(i+1,j)){returntrue}// 分支2:删除右字符 j-1if(isPalindrome(i,j-1)){returntrue}returnfalse;}// 测试用例console.log(validPalidrome("abca"))// trueconsole.log(validPalidrome("abc"))// falseconsole.log(validPalidrome("a"))// trueconsole.log(validPalidrome("ab"))// false踩坑提醒
源码原始笔误bug修复:原代码第二判断写了!isPalindrome会直接逻辑反转,面试手写一定要注意取反符号,上面代码已修正可直接使用。
四、面试刷题总结
1. 字符串反转核心流程
字符串 → split转数组 → reverse反转 → join拼接字符串
2. 回文两类实现取舍
快速写代码、短字符串:使用split+reverse API写法
追求空间复杂度、大厂算法面试:优先双指针遍历
3. 最多删1字符回文解题模板
双指针匹配冲突 → 两种删除分支校验 → 任一成立返回true
4. JS底层加分知识点(面试官追问必背)
原始字符串靠包装类实现对象方法调用;
toString区分对象类型,JSON.stringify序列化对象;call借用函数,修改this指向。