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

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

搞懂字符串题,先要建立两个最朴素的认知:不可变性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)

写在最后

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

相关推荐
AOwhisky2 小时前
Kubernetes 学习笔记:集群管理、命名空间与 Pod 基础
linux·运维·笔记·学习·云原生·kubernetes
code_pgf2 小时前
Octo 算法详解-开源通用机器人策略模型技术报告
算法·机器人·开源
嘻嘻哈哈樱桃3 小时前
牛客经典101题题解集--动态规划
java·数据结构·python·算法·职场和发展·动态规划
小龙在慢慢变强..3 小时前
目录结构(FHS 标准)
linux·运维·服务器
2035去旅行3 小时前
嵌入式开发,如何选择C标准库
linux·arm开发
刘延林.3 小时前
win11系统下通过 WSL2 安装Ubuntu 24.04 使用RTX 5080 GPU
linux·运维·ubuntu
脱氧核糖核酸__3 小时前
LeetCode热题100——234.回文链表(两种解法)
c++·算法·leetcode·链表
IronMurphy3 小时前
【算法四十二】118. 杨辉三角 198. 打家劫舍
算法