【数据结构与算法】Manacher算法

2023-05-16

Manacher算法

https://github.com/SongJianHIT/DataStructurs-Algorithm/tree/main/src/algorithms/manacher

基本介绍

Manacher 算法常用于 求一个字符串中的最长回文子串。如:abc123321def 的最长回文子串为 123321

计算字符串的最长回文字串最简单的算法就是枚举该字符串的每一个子串,并且判断这个子串是否为回文串,这个算法的时间复杂度为 O ( N 3 ) O(N^3) O(N3) 的。Manacher 算法可以在 线性时间复杂度 O ( N ) O(N) O(N) 内求出一个字符串的最长回文字串,达到了理论上的下界。

Manacher 算法原理与实现

首先,Manacher 算法提供了一种巧妙的办法,将长度为奇数的回文串和长度为偶数的回文串一起考虑,具体做法是,在原字符串的每个相邻两个字符中间插入一个分隔符,同时在首尾也要添加一个分隔符,分隔符的要求是不在原串中出现,一般情况下可以用 # 号。如:

image-20230105112016065

概念:回文直径与回文半径

举个例子,如字符串 abc12321def 的回文子串为 12321,因此回文直径为 5,回文半径为 3;又如字符串 1221,回文直径为 4,回文半径为 2。

概念:回文半径数组 pArr

原始串再添加了特殊字符 # 后,得到处理串。

我们在处理串上,对每个字符 T[i],记录以 T[i] 为中心的最长回文字串的最右字符到 T[i] 的长度**(回文半径)**。比如以 T[i] 为中心的最长回文字串是 T[l,r],那么 Len[i]=r-i+1

概念:最右回文边界 R

最右回文边界是一个 int 类型整数。初始值 int R = -1;。他的含义是,不管是从哪个位置 i 作为中心点向左右两边扩,只要扩出来的回文区域的右边界更靠右了,就更新 R

概念:取得最右回文右边界的中心 C

取得最右回文右边界的中心是一个 int 类型整数。初始值 int C = -1;R 只要更新,C 就负责记录是哪个中心点扩的时候让 R 更新了。

对上述概念举个例子:

IMG_42D84C15A973-1

算法流程

Manacher 算法从 index=0 开始,以 str'[index] 为中心,向左右两边扩,找最长回文子串。

index=i 时,有如下几种情况:

  1. i 没有被 R 扩住,即 i > R

    此时,无法优化,暴力扩就行了。

  2. iR 扩住,即 i <= R

    此时存在这种拓扑关系 [L i' C i R]i'i 关于 C 的对称点。比较特殊的是 iR 重叠,但讨论一样。

    接下来,分类讨论:

    • 情况 1i' 扩出来的区域彻底在 [L, R]

      IMG_EDD6997AF5DB-1

      此时,i 不用扩了,i 的回文区域大小与 i' 一样大。

    • 情况 2i' 扩出来的区域跑到 [L, R] 外面了

      IMG_723D1305D386-1

      此时,i 不用扩了,i 的回文区域只会到 R,回文半径可计算为 R - i + 1

    • 情况 3i' 的左边界与回文区域重合

      IMG_2FB5E0AEEEEC-1

      此时,i 的回文区域至少是 i' 那么大,但还有可能更大!

经典题目

题目一:最少添加多少字符变成回文串

在一个字符串中,只能够在字符串的后面添加字符,最少需要添加多少个字符,使其能够变成回文串。

如:str=[abc12321],要使其变成回文串,最少需要 3 个字符 [cba]

解决方法

这道题实际上是在求,必须包括最后一个字符的情况下,最长回文子串是多长,长度记为 x。字符串总长度为 len,要使其变为回文串,则最少需要 len - x 个字符即可。

只要找到 必须包括最后一个字符的情况下,最长回文子串是多长 后,把前面的字符串逆序即可。

怎么找呢?

  • 每个 index 都推出一个右边界,当右边界到达最后一个字符串时,停!就找到此时的中心 C,这就是最长回文串的中心。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

【数据结构与算法】Manacher算法 的相关文章

  • 数据库多维迭代算法

    关键词 数据库 迭代 递归 多维 一 两种传统的数据库迭代结构算法 对于数据库的迭代结构 有两种传统的算法 递归算法和边界算法 比如对于下面图1的结构 图1 递归算法的数据结构如表1所示 节点id 节点值 父节点id 1 1111 2 3
  • 50个c/c++源代码网站

    C C 是最主要的编程语言 这里列出了50名优秀网站和网页清单 这些网站提供c c 源代码 这份清单提供了源代码的链接以及它们的小说明 我已尽力包括最佳的C C 源代码的网站 这不是一个完整的清单 您有建议可以联系我 我将欢迎您的建 议 以
  • 算法--将数组分成和相等的多个子数组,求子数组的最大个数

    作者 陈太汉 一个整数数组 长度为n 将其分为m份 使各份的和相等 求m的最大值 比如 3 2 4 3 6 可以分成 3 2 4 3 6 m 1 3 6 2 4 3 m 2 3 3 2 4 6 m 3 所以m的最大值为3 算法 原理的思想是
  • LeetCode83: 删除排序链表中的重复元素

    给定一个已排序的链表的头 head 删除所有重复的元素 使每个元素只出现一次 返回 已排序的链表 示例 1 输入 head 1 1 2 输出 1 2 示例 2 输入 head 1 1 2 3 3 输出 1 2 3 提示 链表中节点数目在范围
  • 直线检测方法—LSD论文翻译

    附原文链接 LSD a Line Segment Detector 摘 要 LSD是一个线段检测器 能够在线性时间内得到亚像素级精度的检测结果 它无需调试参数就可以适用于任何数字图像上 并且能够自我控制错误数量的检测 平均来说 一个图像中允
  • 白盒测试相关的一些知识

    在白盒测试中 可以使用各种测试方法进行测试 下面这篇文章 可能比较枯燥 如果不乐意读 可以先收藏 如果在你的工作中真遇到白盒测试的话 可以回过头再来看看 还是值得读一读 一般来说 白盒测试时要考虑以下5个问题 1 测试中尽量先用自动化工具来
  • Qt——用于表格QTableView的模型

    如果想使用表格来呈现数据 Qt提供了一个方便的部件QTableWidget 但是直接用它实现一些功能可能比较困难 这里将介绍一种强大 灵活的方式来操作表格 一 模型 视图架构 在这个架构中 模型用于存储数据 视图用于呈现数据 除此之外 还有
  • findBug 错误修改指南

    FindBugs错误修改指南 1 EC UNRELATED TYPES Bug Call to equals comparing different types Pattern id EC UNRELATED TYPES type EC c
  • 递归算法中的时间复杂度分析

    对于一种算法的时间复杂度分析还是特别重要的 在一些非递归算法中 我们仅仅看运算次数最多的那一行代码可能执行多少次就可以 实际就是看在循环中变量的变化 但是对于递归算法中该怎么分析呢 下面介绍几种递归函数中的算法时间复杂度分析的方法 0 递推
  • 亚利桑那州立大学周纵苇:研习 U-Net ——现有的分割网络创新

    雷锋网AI研习社按 经典的 Encoder Decoder 结构在目标分割问题中展现出了举足轻重的作用 然而这样一个相对固定的框架使得模型在感受野大小和边界分割精度两方面很难达到兼顾 本次公开课 讲者以 U Net 为案例分析 总结现有的分
  • 数据结构与算法书籍推荐

    学习数据结构与算法 还是很有必要看几本相关的书籍 但根据不同基础的人 合适看的书也不一样 因此 针对不同层次 不同语言的人 推荐几本市面上口碑不错的书 1 入门级 针对刚入门的同学 建议不要急着去看那些经典书 像 算法导论 算法 这些比较经
  • 字符串09--表示数值的字符串

    字符串09 表示数值的字符串 jz53 题目概述 解析 参考答案 注意事项 说明 题目概述 算法说明 请实现一个函数用来判断字符串是否表示数值 包括整数和小数 例如 字符串 100 5e2 123 3 1416 和 1E 16 都表示数值
  • 4Sum

    Given an array S of n integers are there elements a b c and d in S such that a b c d target Find all unique quadruplets
  • 堆栈01--用两个栈实现队列

    堆栈01 用两个栈实现队列 jz05 题目概述 解析 参考答案 注意事项 说明 题目概述 算法说明 用两个栈来实现一个队列 完成队列的Push和Pop操作 队列中的元素为int类型 测试用例 队列先进先出 输入 1 2 输出 1 2 解析
  • 算法学习——贪心算法之币种统计

    算法描述 币种统计 单位给每一位员工发工资 精确到元 为了保证不临时换零钱 使得每个员工取款的张数最少 在取工资前统计所有员工所需要的各种票面的张数 约定票种为100 50 20 10 5 2 1元 并验证币种统计是否正确 算法思路 算法描
  • CRC校验(二)

    CRC校验 二 参考 https blog csdn net liyuanbhu article details 7882789 https www cnblogs com esestt archive 2007 08 09 848856
  • 机器学习算法GBDT的面试要点总结-上篇

    1 简介 gbdt全称梯度提升决策树 在传统机器学习算法里面是对真实分布拟合的最好的几种算法之一 在前几年深度学习还没有大行其道之前 gbdt在各种竞赛是大放异彩 原因大概有几个 一是效果确实挺不错 二是即可以用于分类也可以用于回归 三是可
  • 【试题】排列组合

    在写一个远程的代码 如果本地有M个显示器 远程有N个显示器 M lt N 依据分辨率 显示器刷新频率等要求 需要对远程的N个显示器进行最佳分辨率修改 之后 需要从N个远程显示器中选择M个 跟本地显示器进行一对一的匹配 即从 A N M N
  • 数组实现循环队列(增设队列大小size)

    目录 一 前言 1 如何实现循环 2 如何判断队列为空 3 如何判断队列为满 二 循环队列的结构定义 三 循环队列的创建及其初始化 四 入队 五 出队 六 取队头元素 七 取队尾元素 八 循环队列判空 九 循环队列判满 十 循环队列销毁 一
  • 排序:计数排序

    一 概念 计数排序是非比较排序 是对哈希直接定址法的变形应用 二 思想 利用数组统计相同数据出现的次数 例如整型数据m出现n次 就在数组m位置记录数据为n 最后从头遍历数组打印数据即可 通俗来讲就是 数组下标即为数据 下标所指位置的值即为数

随机推荐

  • gstreamer学习笔记---gst-omx

    一 openMAX理解1 gst omx是基于openMAX开发的插件 xff0c 所以在介绍gst omx之前 xff0c 我们先了解一下openMAX openMAX xff1a open media acceleration xff0
  • csi mipi信号解析

    1 传输模式 LP xff08 Low Power xff09 模式 xff1a 用于传输控制信号 xff0c 最高速率 10 MHz HS xff08 High Speed xff09 模式 xff1a 用于高速传输数据 xff0c 速率
  • 程序调试方法

    记录初衷 xff1a 遇到问题 xff0c 按照一套方法 xff0c 把问题化解 xff0c 逐渐的内化为心法 xff0c 形成经验 xff0c 这就是成长的过程 就好比吃的猪肉 xff0c 经过消化 分解 吸收后变成了自己肉 程序分为三种
  • 博客八:基于xr871实现wifi音响产品

    原创 xff1a http blog csdn net kylin fire zeng xff0c 欢迎转载分享 xff0c 共同进步 xff0c 但请注明出处啊 xff0c 尊重他人成果
  • 用 Docker 部署一个 Python 应用

    Flask项目 这里为了演示的方便 xff0c 我们就写一个简单的Flask项目 xff0c 代码如下 from flask import Flask app 61 Flask name 64 app route 39 39 def ind
  • Realsence D455标定并运行Vins-Fusion

    文章目录 一 双目相机标定1 标定板准备1 1 打印标定板1 2 标定板信息原始pdf的格子参数是 xff1a 调整后的格子参数是 xff1a 2 左右目相机数据准备2 1 修改rs camera launch内容2 2 关闭结构光2 3
  • 【Linux命令】文件和目录权限

    Linux命令 文件和目录权限 权限查看 众所周知 xff0c 可以使用 ls l 来查看文件和目录的详细信息 xff0c 那么输出的东西是什么呢 xff1f 我们先来看 文件类型 xff1a xff1a 普通文件 xff1b d xff1
  • 【设计模式】单例模式

    设计模式 单例模式 1 为什么要用单例 xff1f 单例设计模式 xff08 Singleton Design Pattern xff09 xff1a 一个类只允许创建一个对象 xff08 或实例 xff09 1 1 处理资源访问冲突 例如
  • 【JAVA】基础语法

    JAVA 基础语法 JAVA面向对象三大特征 封装 继承 多态 1 类型转换 1 1 自动类型转换 自动类型转换 类型范围小的变量 可以直接赋值给类型范围大的变量 1 2 表达式的自动类型转换 在表达式中 小范围类型的变量会自动转换成当前较
  • 【Java技巧】如何在HashMap中插入重复的key?

    Java技巧 如何在HashMap中插入重复的key xff1f 问题引出 我们都知道 xff0c Map 的 key 需要保证唯一性 插入重复的 key 会被最后插入的 key 所覆盖 xff0c 如 xff1a span class t
  • ArrayList源码分析

    ArrayList源码分析 注意 本笔记分析对象为 Java8 版本 随版本不同 源码会发生变化 1 ArrayList类图与简介 ArrayList是一个 非线程安全 基于数组实现的一个动态数组 可以看到 它的顶层接口是 Collecti
  • Vector源码分析

    Vector源码分析 1 Vector基本介绍与类图 Vector 类实现了一个动态数组 和 ArrayList 很相似 但是两者是不同的 Vector 是同步访问的 Vector 包含了许多传统的方法 这些方法不属于集合框架 Vector
  • LinkedList源码分析

    LinkedList源码分析 注意 本笔记分析对象为 Java8 版本 随版本不同 源码会发生变化 基本介绍与类图 LinkedList 同时实现了 List 接口和 Deque 对口 也就是收它既可以看作一个顺序容器 又可以看作一个队列
  • 【网管日记】Linux防火墙操作

    网管日记 Linux防火墙操作 记录一下常用的Linux防火墙操作 xff1a 查看防火墙状态 systemctl status firewalld 或 firewall cmd state暂时关闭防火墙 systemctl stop fi
  • (毕业设计资料)基于51单片机的智能窗控制系统设计

    实现参考功能 1 可实时显示年月日 时分秒 光照强度和控制模式 xff1b 2 可通过手动控制窗帘的开启和关闭 xff1b 3 可通过设置开启和关闭时间来控制窗帘 xff1b 4 可通过检测光照强度的亮暗来控制窗帘 xff1b 5 使用步进
  • 网络操作系统 第十二章 FTP服务器的安装与配置

    习题 1 简述FTP的连接模式 FTP的连接模式有PORT和PASV两种 xff0c 其中PORT模式是主动模式 xff0c PASV是被动模式 xff0c 这里所说的主动和被动都是相对于服务器而言的 如果是主动模式 xff0c 数据端口为
  • 【网管日记】MySQL主从复制

    MySQL主从复制 基本介绍 MySQL 主从复制是一个异步的复制过程 xff0c 底层是基于 Mysql 数据库自带的 二进制日志 功能 一台或多台 MySQL 数据库 xff08 slave xff0c 即 从库 xff09 从另一台
  • 【网管日记】Nginx基本介绍、安装与使用

    Nginx基本使用 基本介绍 Nginx是一款轻量级的Web服务器 反向代理服务器及电子邮件 xff08 IMAP POP3 xff09 代理服务器 其特点是 占用内存少 xff0c 并发能力强 xff0c 事实上nginx的并发能力在同类
  • 【网管日记】Nginx报错踩坑记录

    网管日记 Nginx报错踩坑记录 1 防火墙没关闭 自启 error 21113 0 21 connect failed 113 No route to host while connecting to upstream 解决方法 xff1
  • 【数据结构与算法】Manacher算法

    Manacher算法 https github com SongJianHIT DataStructurs Algorithm tree main src algorithms manacher 基本介绍 Manacher 算法常用于 求一