字符串

一、最小表示法:找循环字符串的"最小值"

什么是最小表示法?简单说,对于一个字符串S,它的循环移位(比如将"abcd"左移一位变成"bcda")有很多种,最小表示法就是其中字典序最小的那个。

比如字符串"abba",它的循环移位有"abba"、"bbaa"、"baab"、"aabb",其中字典序最小的是"aabb",这就是它的最小表示。

算法核心思路

最小表示法的高效求解依赖于两个指针和一个匹配长度变量,具体步骤如下:

  1. 初始化:设两个指针i=0,j=1(表示两个候选起始位置),匹配长度k=0,字符串长度为N。
  2. 比较字符:比较S[(i+k)%N]和S[(j+k)%N](取模是为了处理循环移位):
    • 若两字符相等:k++,继续比较下一位;
    • 若S[(i+k)%N] > S[(j+k)%N]:说明从i开始的字符串更"大",可以直接淘汰i到i+k的所有位置,令i=i+k+1,k重置为0;
    • 若S[(i+k)%N] < S[(j+k)%N]:同理,淘汰j到j+k的位置,令j=j+k+1,k重置为0。
  3. 终止条件:当i或j超过N时,较小的那个指针就是最小表示的起始位置。

为什么高效?

这个算法的关键是指针永不后退,每次"淘汰"操作至少让指针前进1位。因此i和j的总移动距离不超过2N,每个字符最多被比较常数次,整体时间复杂度是O(N),线性高效。

二、Z函数:快速找前缀匹配长度

Z函数(Z-function)是字符串前缀匹配的利器,定义如下:对于字符串s,Z[i]表示s与s[i:](从i开始的后缀)的最长公共前缀长度,且规定Z[0]=0。

举个例子,对于s= "aaaabaaaab",它的Z数组是[0,3,2,1,0,5,3,2,1,0]:

  • Z[1]=3:s[0..2]("aaa")与s[1..3]("aaa")匹配;
  • Z[5]=5:s[0..4]("aaaab")与s[5..9]("aaaab")完全匹配。

算法核心思路

计算Z数组的关键是维护一个"当前最右匹配段"[l, r](即s[l..r]是s的前缀),利用已计算的Z值减少重复比较:

  1. 初始化:l=0,r=0(初始无匹配段),从i=1开始计算Z[i]。
  2. 分情况处理
    • 若i ≤ r:根据[l, r]的性质,s[i..r] = s[i-l..r-l],因此Z[i]至少为min(Z[i-l], r-i+1)。若Z[i-l] < r-i+1,则Z[i] = Z[i-l];否则需要从r+1开始暴力扩展。
    • 若i > r:直接从s[i]开始暴力比较,计算Z[i]。
  3. 更新匹配段:计算完Z[i]后,若i+Z[i]-1 > r,则更新l=i,r=i+Z[i]-1。

应用场景

Z函数可用于解决前缀匹配相关问题,比如:

  • 判断一个字符串是否是另一个的循环移位(结合最小表示法);
  • 查找字符串中所有与某个前缀匹配的位置。

三、AC自动机

AC自动机(Aho-Corasick Automaton)是专门用于多模式匹配的算法,简单说就是给定一堆模式串(比如关键词),快速在一个文本串中找到所有出现的模式串。

比如在文章中高亮所有敏感词,就可以用AC自动机高效实现,比逐个用KMP匹配快得多。

核心特点

  • 基于字典树(Trie)构建,同时增加了"失败指针"(类似KMP的next数组),用于在匹配失败时快速跳转,避免重复比较。
  • 构建过程分三步:建字典树→求失败指针→模式匹配,整体时间复杂度与模式串总长度和文本串长度线性相关。

四、回文树:处理回文串的专属工具

回文树(Palindromic Tree,又称回文自动机)是专门用于统计和处理字符串中回文子串的结构,能高效找到所有不同的回文子串,以及它们的出现次数等信息。

核心特点

  • 维护两种节点:分别对应长度为偶数和奇数的回文子串;
  • 每个节点记录回文串的长度、后缀链接(类似失败指针)等信息;
  • 构建过程中,每次添加一个字符,通过后缀链接快速找到以该字符结尾的最长回文子串,时间复杂度线性。
posted @ 2025-08-06 19:26  ᝰꫛꫀꪝ_yqy  阅读(28)  评论(0)    收藏  举报
/**手机适配**/ @media only screen and (max-width: 767px) { header{width:100%} .banner{width: 100%;height: 100px;} .avatar{width: 80px;height: 80px;margin: 6px;} .avatar a{padding-top: 59px;width: 80px;height: 80px;background-size: 80px 78px;} .avatar a span{margin-top: 0px; padding-top: 0px; width: auto;height: auto;} .bloglist h3 {margin: 20px 0 10px 10px;} .bloglist figure {width:auto;margin-left: 4px;} .bloglist figure img {width: 90px;height: 60px;} .bloglist ul{width:64%} .dateview {width:100%;padding-left:4px;} .dateview span {margin: 0 3px;} .weixinnone,.thumbs{display: none} .right{width: 100%;margin-top: 22px} .right ul{width:64%;margin-left: 22px;} .weather{margin: 20px 50px;} .bloglinkli{display: block} footer{width:100%} }