面试常客:字符串算法从入门到进阶

最近在整理算法笔记时,发现字符串相关的面试题真是常青树。今天就借着我的学习笔记,和大家聊聊字符串算法中的几个经典问题,以及JS中一些容易被忽略的底层细节。


一、反转字符串,你真的会了吗?

先来个开胃菜------反转字符串。别看它简单,里面藏着不少JS的"坑"和设计哲学。

最直接的解法

javascript

ini 复制代码
const str = 'abc';
const res = str.split('').reverse().join('');
console.log(res); // 'cba'

核心思路就三步:

  1. split('') ------ 把字符串拆成字符数组
  2. reverse() ------ 反转数组
  3. join('') ------ 把数组拼回字符串

为什么不能直接在字符串上调用 reverse()

因为字符串是简单数据类型 (基本类型),而 reverse() 是数组原型上的方法。JS 的字符串并没有提供 reverse API,但数组有。

包装类的"魔法"

你可能好奇过:既然 str 是简单数据类型,为什么 str.length 能用?

javascript

ini 复制代码
const str = 'abc';
console.log(str.length); // 3

这背后其实是 JS 的包装类 在悄悄工作。当我们试图访问基本类型的属性时,JS 底层会临时用 new String(str) 把它包装成一个 String 对象实例,调用完属性/方法后,再把它"打回原形"变回简单数据类型。

就像灰姑娘的魔法,到了点就恢复原样 ✨

javascript

javascript 复制代码
const str2 = new String("abc"); // 这才是真正的字符串对象
console.log(str2.length); // 3
console.log(Object.prototype.toString.call(str2)); // "[object String]"

二、一切皆对象,Object.prototype.toString 的妙用

在学习过程中,有一个知识点让我豁然开朗 ------ Object.prototype.toString 的作用。

javascript

css 复制代码
let o = { a: 1, b: 2 };
o.toString(); // "[object Object]"
JSON.stringify(o); // '{"a":1,"b":2}'

toString() 的职责是把对象序列化(字符串化) ,而 JSON.stringify 则是更严格的 JSON 序列化。

但为什么 [1,2,3].toString() 返回的是 '1,2,3',而普通对象的 toString 返回 "[object Object]"

因为不同的子类型重写了 toString 方法,用来细化类型的区分 。这也是为什么我们可以用 Object.prototype.toString.call(obj) 来精准判断一个变量的类型:

javascript

javascript 复制代码
Object.prototype.toString.call([])   // "[object Array]"
Object.prototype.toString.call(null) // "[object Null]"
Object.prototype.toString.call({})   // "[object Object]"

顺便提一句笔记里的重点:call 可以让一个方法借给其他对象使用,这是 JS 函数式特性的体现。

javascript

javascript 复制代码
let o = {
  name: '胡老板',
  say: function() {
    console.log('我是' + this.name);
  }
};

let obj = { name: '张三' };
o.say.call(obj); // '我是张三' ------ this 被指向了 obj

三、判断回文字符串

回文字符串:正着读和反着读都一样。比如 'abcba''racecar'

解法一:API 流(简洁但不一定高效)

javascript

lua 复制代码
function isPalindrome(str) {
    return str === str.split('').reverse().join('');
}

解法二:双指针(推荐)

利用对称特性,从两端往中间比较:

javascript

ini 复制代码
function isPalindrome(str) {
    const len = str.length;
    for (let i = 0; i < len / 2; i++) {
        if (str[i] !== str[len - 1 - i]) {
            return false;
        }
    }
    return true;
}

小细节 :为什么把 len 存成变量而不是每次都 str.length?因为 str.length 在循环中每次访问都有开销(涉及包装类的临时转换),而存在栈内存的变量访问更快。虽然微乎其微,但好习惯要从细节养成。


四、进阶:最多删除一个字符的回文判断

这是回文字符串的经典衍生题,也是面试中的常客:

给定一个非空字符串 s,最多删除一个字符。判断是否能成为回文字符串。

比如 'abca',删除 'c''b' 后可以得到 'aba''aca',都是回文。

思路分析

双指针从两端向中间移动,遇到不匹配的字符时,有两种删除策略:

  • 删除左边的字符,检查 [i+1, j] 区间是否是回文
  • 删除右边的字符,检查 [i, j-1] 区间是否是回文

只要其中一种成立,就返回 true

代码实现

javascript

ini 复制代码
function validPalindrome(s) {
    const len = s.length;
    let i = 0;
    let j = len - 1;

    while (i < j && s[i] === s[j]) {
        i++;
        j--;
    }

    // 删除左边一个,检查 [i+1, j]
    if (isPalindrome(i + 1, j)) {
        return true;
    }
    // 删除右边一个,检查 [i, j-1]
    if (isPalindrome(i, j - 1)) {
        return true;
    }

    // 辅助函数:检查 s 在 [i, j] 区间是否是回文
    function isPalindrome(i, j) {
        while (i < j) {
            if (s[i] !== s[j]) {
                return false;
            }
            i++;
            j--;
        }
        return true;
    }

    return false; // 两种删除策略都失败
}

举例理解

'aacvdafafdvcaa' 为例:

双指针一直向内移动,直到遇到第一对不相等的字符时停下,此时 ij 指向的就是需要"二选一"删除的位置。然后分别尝试删左或删右,看剩下的部分是否回文。


写在最后

字符串算法看似简单,但要想写得优雅且考虑周全,需要对 JS 的数据类型、原型链、底层包装类等有深入理解。

这四道题从基础到进阶,正好构成了一个完整的学习路径:

  1. 反转字符串 ------ 熟悉数组和字符串的 API 配合
  2. 包装类机制 ------ 理解 JS 底层的设计哲学
  3. 回文判断 ------ 掌握双指针技巧
  4. 删除一个字符的回文判断 ------ 举一反三,灵活运用

希望这篇文章对你有所帮助。如果有什么问题或者想探讨更多细节,欢迎在评论区交流~

相关推荐
大志说编程2 小时前
Agent面试真题06: 十分钟带你快速掌握Agent记忆管理高频面试题(附详细答案)
后端·面试·ai编程
众人皆醒我独醉2 小时前
Kubernetes 为什么不直接调度容器?非要套一层 Pod
面试
吴佳浩4 小时前
DeepSeek DSpark:Confidence-Scheduled Speculative Decoding 技术解析
人工智能·算法·deepseek
亮亮不想说话958884 小时前
iOS底层探索 -- GCD分析
面试
程序员小假5 小时前
从问题到答案:RAG系统完整处理流程与核心机制深度拆解
后端·面试·agent
触底反弹5 小时前
🧠 搞懂 Token,才算真正入门大模型——从分词原理到 Embedding 语义实战
javascript·人工智能·算法
vivo互联网技术9 小时前
ICLR 2026 | 基于后验采样的图像恢复方法LearnIR:人脸去阴影、去雾
人工智能·算法·aigc
沉默王二10 小时前
阿里一面,我霸气反问:你说你们在做Agent项目,说说langchain、muti-agent、a2a这些你们都是怎么做的?面试官一直在擦汗。。
面试·agent·ai编程
浮生望10 小时前
JS字符串与回文算法:从包装类到双指针的面试进阶之路
javascript·算法