【算法复习】字符串 | 两个底层直觉,吃透高频题

一、字符串算法的两个底层直觉

搞懂字符串题,先要建立两个最朴素的认知:不可变性ASCII 映射。理解了它们,绝大多数题目都能套上模板。

1. 字符串的「不可变性」(Immutability)

在 JavaScript 中,字符串是按值传递且不可变的。你无法像操作数组那样直接通过 s[0] = 'a' 来修改某一位的字符。

破局点 :当遇到需要 修改、翻转、替换 字符串中特定位置字符的题目时,第一反应永远是------先转成数组处理,最后再拼回来

套路代码:

jsx 复制代码
let arr = s.split('')
// ...在数组上做各种操作...
return arr.join('')

2. 字符的「ASCII 映射」(CharCode)

很多字符串题目限定了「只包含小写字母」,这意味着字符的种类被严格限制在了 26 个。

破局点 :不要总是依赖 MapObject。利用字符的 ASCII 码差值,构建一个长度为 26 的数组作为「计分板」,是空间复杂度最优(真正的 O(1))的解法。

套路代码:

jsx 复制代码
const index = char.charCodeAt(0) - 97 // 97 是 'a' 的 ASCII 码

二、核心题型与通用模板

结合已通关的题目,字符串考察主要分为两大阵营。

阵营 A:字母异位词与词频统计(哈希 / 数组计分板)

这类题目的本质是:忽略字符的顺序,只关注字符出现的种类和频率

通用模板:26 位定长数组计分板

如果题目只有小写字母,直接初始化一个长度为 26、全为 0 的数组。遍历第一个字符串时执行 +1,遍历第二个字符串时执行 -1。最后检查数组是否全为 0。

jsx 复制代码
const count = new Array(26).fill(0)
for (const ch of s) count[ch.charCodeAt(0) - 97]++
for (const ch of t) count[ch.charCodeAt(0) - 97]--
return count.every(n => n === 0)
对应练习题(按难度递增)
  • LeetCode 242. 有效的字母异位词:最基础的计分板应用,跑通模板即可。
  • LeetCode 383. 赎金信:变种题,检查计分板中是否有任何一项小于 0。
  • LeetCode 49. 字母异位词分组 :进阶应用,需要将计分板转换回字符串(或使用排序后的字符串)作为 Map 的 Key,把具有相同特征的字符串分到同一个数组里。
  • LeetCode 438. 找到字符串中所有字母异位词:综合应用题。将「计分板」与「定长滑动窗口」结合,在父串上滑动,每次只维护进出窗口的两个字符的状态。

阵营 B:回文串与反转问题(双指针)

这类题目的本质是:关注字符的对称性和顺序颠倒

通用模板:相向双指针

定义 left = 0right = s.length - 1,两个指针不断向中间靠拢,在遍历过程中进行对比或交换操作。

jsx 复制代码
let left = 0, right = s.length - 1
while (left < right) {
	// 对比 or 交换 s[left] 与 s[right]
	left++
	right--
}
对应练习题
  • LeetCode 344. 反转字符串 :最纯粹的双指针交换。考察 JS 数组中 [arr[i], arr[j]] = [arr[j], arr[i]] 的解构交换语法。
  • LeetCode 125. 验证回文串:大厂高频题。考察正则表达式去除非字母数字字符,配合双指针忽略大小写进行对比。

三、前端必备 String API 备忘录

在刷题和面试时,以下 API 是必须形成肌肉记忆的:

API 方法 核心用途 算法常见场景
split('') 字符串转数组 涉及元素交换、反转时必须先执行此步
join('') 数组转字符串 输出最终结果
substring(start, end) 截取子串 滑动窗口提取特定片段
charCodeAt(index) 获取字符 ASCII 码 计算索引差值,构建定长数组「桶」
toLowerCase() 统一转小写 忽略大小写的回文 / 异位词比较
match(/[a-z0-9]/ig) 正则提取有效字符 过滤标点符号和空格(如 LeetCode 125)

写在最后

字符串题看似花样繁多,但拆开来看无非两类:频率问题 用计分板,顺序 / 对称问题 用双指针。再叠加一个「不可变 → 转数组」的预处理直觉,几乎可以覆盖大部分常见考点

相关推荐
测试修炼手册4 小时前
[测试工具] 用 Codex 做测试实战:从需求分析到自动化用例落地
运维·自动化·需求分析
Dlrb12114 小时前
C语言-指针三
c语言·算法·指针·const·命令行参数
米高梅狮子4 小时前
03.网络类服务实践
linux·运维·服务器·网络·kubernetes·centos·openstack
June`5 小时前
网络编程时内核究竟做了什么???
linux·服务器·网络
Tisfy5 小时前
LeetCode 2540.最小公共值:双指针(O(m+n))
算法·leetcode·题解·双指针
IronMurphy5 小时前
【算法四十七】152. 乘积最大子数组
算法
楼兰公子5 小时前
RK3588 + Linux7.0.3 网络工程调试错误速查手册
linux·网络·3588
Elnaij5 小时前
Linux系统与系统编程(9)——自设计shell与基础IO
linux·服务器
IpdataCloud6 小时前
稳定的企业级IP数据接口怎么选?可用性指标+离线库高可用方案
运维·网络·tcp/ip
WebGIS开发6 小时前
地信职业百科②:GIS运维
运维·gis·就业·转行