当前位置: 首页 > news >正文

manacher算法详解

例题

  • 求一个字符串的最长回文子串的长度

O(N2)O(N^2)O(N2)的解法很容易想,就是从每个字符位置向左右同时拓展,然后检查当前是不是回文,更新长度,可以简单写一下代码

int solve(string &ss){int ans = 0;int n = ss.length();string s;s.resize(2 * n + 1);int l = 0;s[l++] = '$';s[l++] = '#';for(int i=0;i<n;i++){s[l++] = ss[i];s[l++] = '#';}for(int i=0;i<l;i++){int p = 0;while(i - p >= 0 && i + p < l && s[i + p] == s[i - p]){p += 1;}ans = max(ans, p - 1);}return ans;
}
  • 这里注意一个小技巧,一个字符串有两种情况,分别是长度为奇数和长度为偶数,如何将这两种情况归一化呢?考虑在字符串前面加一个$,在每两个字符之间放一个#,不一定非得是$和#,只要不会在字符串中出现即可,容易计算得到这样做得到的字符串长度一定是奇数
  • 考虑优化,容易想到如果计算已经得到了前面的回文半径(以某个字符为中心的回文串长度的一半),那么对称的两个点中尚未计算的那个点的回文半径的最小值也就是已经计算得到的那个点的回文半径
    在这里插入图片描述
  • 观察上面的字符串,第一个红色的b的回文半径容易求出是2,后面的c的回文半径容易求出是6,那么我们如何根据它求出后面的红色的b的回文半径呢?显然因为c的回文半径范围覆盖了第一个红色的b,所以第二个红色的b的回文半径的最小值是第一个红色的b的回文半径(这里同时因为c的回文半径也覆盖了第二个红色的b的回文半径区域,因为如果第二个红色的b之后没有足够的字符也是到不了第一个红色的b的回文半径的),这样我们就得到了第二个b的回文半径的最小值,然后暴力拓展,就为之后的字符串也做好了铺垫,可以证明总的时间复杂度是O(n)O(n)O(n)
  • 上面是我对manacher算法的个人理解,接下来从代码的角度来说一下,首先需要两个变量rc,因为有一个问题,怎么判断某个字符是不是在某个回文区间之内,我们可以从左边递推找到一个右端点最远的回文区域,这样记录一下中心端点c和右端点r,在从左到右计算的过程中更新最大的r,这样就找到了回文半径和回文中心
  • 然后使用一个数组P[i]记录以i为中心的回文半径,具体代码如下
int manacher(string &ss){int n = ss.length();string s;s.resize(2 * n + 1);int l = 0;s[l++] = '$';s[l++] = '#';for(int i=0;i<n;i++){s[l++] = ss[i];s[l++] = '#';}vector<int> P(l);int r, c;r = c = 0;int ans = 0;for(int i=0;i<l;i++){int &p = P[i];// 用r - i约束的原因上面已经说过p = (i + p < r ? min(r - i, P[2 * c - i]) : 1);// 2 * c - i是对称位置的字符while(s[i + p] == s[i - p]) p += 1;if(i + p > r){r = i + p;c = i;}ans = max(ans, p - 1);}return ans;
}

例题

https://www.luogu.com.cn/problem/P4287
在一个字符串里面找前后两个长度相等的子串都是回文串的字符串的最大长度

  • 考虑manacher,如果计算出了一个回文串,因为它的前面已经计算好了,比如现在回文半径右端点最远在rrr,那么从iiirrr这一段是回文串的一半我们是知道的,现在考虑它前面一段,怎么考虑呢?根据对称性,设j≥rj\geq rjr,对称到左边就是i−j−i2i-\frac{j-i}{2}i2ji同时还需要满足(j−i)%4=0(j-i)\%4=0(ji)%4=0,这里的iii是右侧字符串的回文中心,jjj是左侧字符串关于ccc对称的回文中心
  • 因为要求这样的回文串长度必须是偶数,所以根据我们的回文串构造方法,每次枚举的iii必须是奇数
#include <bits/stdc++.h>using namespace std;int main(){ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);int n;string ss;cin >> n >> ss;string s;s.resize(2 * n + 1);int l = 0;s[l++] = '$';s[l++] = '#';for(int i=0;i<n;i++){s[l++] = ss[i];s[l++] = '#';}vector<int> P(l);int r, c;r = c = 0;int ans = 0;for(int i=0;i<l;i++){int &p = P[i];p = (i + p < r ? min(P[2 * c - i], r - i) : 1);while(s[i + p] == s[i - p]) p += 1;if(i + p > r){if(i & 1){for(int j=max(r, i + 4);j<=i+p;j++){if((j - i) % 4 == 0 && P[i - (j - i) / 2] >= (j - i) / 2){ans = max(ans, j - i);}}}r = i + p;c = i;}}cout << ans << '\n';return 0;
}

相关文章:

manacher算法详解

例题 求一个字符串的最长回文子串的长度 O(N2)O(N^2)O(N2)的解法很容易想&#xff0c;就是从每个字符位置向左右同时拓展&#xff0c;然后检查当前是不是回文&#xff0c;更新长度&#xff0c;可以简单写一下代码 int solve(string &ss){int ans 0;int n ss.length();s…...

要做一个关于DDD的内部技术分享,记录下用到的资源,学习笔记(未完)

最后更新于2023年3月10日 14:28:08 问题建模》软件分层》具体结构&#xff0c;是层层递进的关系。有了问题建模&#xff0c;才能进行具体的软件分层的讨论&#xff0c;再有了分层&#xff0c;才能讨论在domain里面应该怎么实现具体结构。 1、问题建模&#xff1a;Domain、Mod…...

KDZD互感器二次负载测试仪

一、概述 电能计量综合误差过大是电能计量中普遍存在的一个关键问题。电压互感器二次回路压降引起的计量误差往往是影响电能计量综合误差的因素。所谓电压互感器二次压降引起的误差&#xff0c;就是指电压互感器二次端子和负载端子之间电压的幅值差相对于二次实际电压的百分数…...

在空投之后,Blur能否颠覆OpenSea的主导地位?

Mar. 2023, Daniel数据源&#xff1a; NFT Aggregators Overview & Aggregator Statistics Overview & Blur Airdrop一年前&#xff0c;通过聚合器进行的NFT交易量开始像滚雪球一样增长&#xff0c;有时甚至超过了直接通过市场平台的交易量。虽然聚合器的使用量从10月到…...

2023年新三板产品及服务研究报告

第一章 概述 全国中小企业股份转让系统&#xff08;英语&#xff1a;National Equities Exchange and Quotations&#xff0c;缩写NEEQ&#xff09;&#xff0c;简称股转系统&#xff0c;是第三家全国性证券交易场所&#xff0c;因挂牌企业均为高科技企业而不同于原转让系统内…...

张力控制之开环模式

张力控制的相关知识也可以参看专栏的其它文章,链接如下: 张力闭环控制之传感器篇(精密调节气阀应用)_RXXW_Dor的博客-CSDN博客跳舞轮对应张力调节范围,我们可以通过改变气缸的气压方式间接改变,张力跳舞轮在收放卷闭环控制上的详细应用,可以参看下面的文章链接,这里我…...

python的django框架从入门到熟练【保姆式教学】第二篇

在上一篇博客中&#xff0c;我们介绍了Django的基础知识&#xff0c;并创建了一个简单的Web应用程序。在本篇教程中&#xff0c;我们将深入探讨Django的模型层&#xff08;Model&#xff09;&#xff0c;它是Django应用程序的核心组件之一。 模型层 Django的模型层是一个对象…...

解决win10的过度保护导致文件下载不了程序不能打开运行

win7看来大概是要离我们远去了&#xff0c;虽然我们还能看见她的背影&#xff0c;但大势所趋&#xff0c;我们也只能慢慢的接受win10进入到我们的日常生活。但win10很多时候过度的保护却给我们带来了不便。这里列举两个最常见的问题&#xff0c;当然我这里也给出了解决方案。 文…...

扬帆优配|业务量大突破,这个行业发展明显向好

近期上市的新股&#xff0c;大都在招股阐明书里公布了本年第一季度成绩预告。 我国快递事务量本年已达200亿件 国家邮政局监测数据显现&#xff0c;到3月8日&#xff0c;本年我国快递事务量已到达200.9亿件&#xff0c;比2019年到达200亿件提前了72天&#xff0c;比2022年提前…...

DJ1-4 计算机网络和因特网

目录 一、协议层及其服务模型 ISO/OSI 七层参考模型 TCP/IP 参考模型 1. 网际协议栈&#xff08;protocol stack&#xff09; 2. 分层&#xff1a;逻辑通信 3. 协议分层与数据 二、攻击威胁下的网络 1. 植入恶意软件 2. 攻击服务器和网络基础设施 3. 嗅探分组 4. 伪…...

Nginx根据$host及请求的URI规则重定向rewrite

项目背景&#xff1a; 将域名请求从默认的80端口转发到443 ssl。本项目特殊之处是一个端口监听多个域名&#xff0c;某些域名还有跳转到特定的地址。 普通情况&#xff1a; server { listen 80; #默认的80端口&#xff0c;非…...

人工智能实验一:使用搜索算法实现罗马尼亚问题的求解

1.任务描述 本关任务&#xff1a; 了解有信息搜索策略的算法思想&#xff1b;能够运用计算机语言实现搜索算法&#xff1b;应用A*搜索算法解决罗马尼亚问题&#xff1b; 2.相关知识 A*搜索 算法介绍 A*算法常用于 二维地图路径规划&#xff0c;算法所采用的启发式搜索可以…...

Spring Security基础入门

基础概念 什么是认证 认证&#xff1a;用户认证就是判断一个用户的身份身份合法的过程&#xff0c;用户去访问系统资源的时候系统要求验证用户的身份信息&#xff0c;身份合法方可继续访问&#xff0c;不合法则拒绝访问。常见的用户身份认证方式有&#xff1a;用户密码登录&am…...

dnsresolver-limit

文件OperationLimiter.h功能DnsResolver是andnroid中提供DNS能力的小型DNS解析器&#xff0c;limit是其中的一个小模块&#xff0c;支持全局、基于key&#xff08;UID&#xff09;的DNS请求限制。DnsResolver是多线程模型&#xff0c;单个DNS请求最多启动3个线程(传统DNS)。在网…...

使用 YoctoProject集成Qt6

By Toradex胡珊逢在嵌入式领域中Qt 作为普遍选择的 UI 方案目前已经发布 Qt6 版本。本文将介绍如何为 Toradex 的计算机模块使用 Yocto Project 将 Qt6 集成到镜像里。首先根据这里的说明&#xff0c;准备好Yocto Project 的编译环境。这里我们选择 Toradex 最新的 Linux BSP V…...

「媒体邀约」如何选择适合的媒体公关,媒体服务供应商

传媒如春雨&#xff0c;润物细无声&#xff0c;大家好&#xff0c;我是51媒体网胡老师。 每天胡老师也会接到大量关于媒体方面的询问&#xff0c;胡老师也都一一的很耐心的进行了解答&#xff0c;也都很详细的做了媒体规划和媒体传播方案&#xff0c;但有的朋友还是很犹豫&…...

html2canvas和jspdf导出pdf,每个页面模块占一页,在pdf中垂直居中显示

需求&#xff1a;html页面转换pdf&#xff0c;页面有多个模块&#xff0c;页面中有文本、echarts、表格等模块&#xff0c;一个模块占一页&#xff0c;因为模块高度不够&#xff0c;所以需要垂直居中 通过html2canvas和jspdf实现&#xff0c;html2canvas用于将页面元素生成canv…...

数学小课堂:集合论的公理化过程(用构建公理化体系的思路来构建自然数)

文章目录 引言I 数的理论1.1 构建自然数1.2 定义整数/有理数/实数/虚数/复数II 自然数和集合的关系1.3 集合1.2 构建自然数III 线性规划问题(线性代数+最优化)3.1 题目3.2 答案引言 数学是一个公理化的体系,是数学对其它知识体系有启发的地方。 数学的思维方式: 不轻易相信…...

3.10多线程

一.常见锁策略1.悲观锁 vs乐观锁体现在处理锁冲突的态度①悲观锁:预期锁冲突的概率高所以做的工作更多,付出的成本更多,更低效②乐观锁:预期锁冲突的概率低所以做的工作少,付出的成本更低,更搞笑2.读写锁 vs 普通的互斥锁①普通的互斥锁,只有两个操作 加锁和解锁只有两个线程针…...

缓存双写一致性之更新策略探讨

问题由来 数据redis和MySQL都要有一份&#xff0c;如何保证两边的一致性。 如果redis中有数据&#xff1a;需要和数据库中的值相同如果redis中没有数据&#xff1a;数据库中的值是最新值&#xff0c;且准备会写redis 缓存操作分类 自读缓存读写缓存&#xff1a; &#xff0…...

IDEA运行Tomcat出现乱码问题解决汇总

最近正值期末周&#xff0c;有很多同学在写期末Java web作业时&#xff0c;运行tomcat出现乱码问题&#xff0c;经过多次解决与研究&#xff0c;我做了如下整理&#xff1a; 原因&#xff1a; IDEA本身编码与tomcat的编码与Windows编码不同导致&#xff0c;Windows 系统控制台…...

华为云AI开发平台ModelArts

华为云ModelArts&#xff1a;重塑AI开发流程的“智能引擎”与“创新加速器”&#xff01; 在人工智能浪潮席卷全球的2025年&#xff0c;企业拥抱AI的意愿空前高涨&#xff0c;但技术门槛高、流程复杂、资源投入巨大的现实&#xff0c;却让许多创新构想止步于实验室。数据科学家…...

Spring Boot 实现流式响应(兼容 2.7.x)

在实际开发中&#xff0c;我们可能会遇到一些流式数据处理的场景&#xff0c;比如接收来自上游接口的 Server-Sent Events&#xff08;SSE&#xff09; 或 流式 JSON 内容&#xff0c;并将其原样中转给前端页面或客户端。这种情况下&#xff0c;传统的 RestTemplate 缓存机制会…...

鸿蒙中用HarmonyOS SDK应用服务 HarmonyOS5开发一个医院挂号小程序

一、开发准备 ​​环境搭建​​&#xff1a; 安装DevEco Studio 3.0或更高版本配置HarmonyOS SDK申请开发者账号 ​​项目创建​​&#xff1a; File > New > Create Project > Application (选择"Empty Ability") 二、核心功能实现 1. 医院科室展示 /…...

将对透视变换后的图像使用Otsu进行阈值化,来分离黑色和白色像素。这句话中的Otsu是什么意思?

Otsu 是一种自动阈值化方法&#xff0c;用于将图像分割为前景和背景。它通过最小化图像的类内方差或等价地最大化类间方差来选择最佳阈值。这种方法特别适用于图像的二值化处理&#xff0c;能够自动确定一个阈值&#xff0c;将图像中的像素分为黑色和白色两类。 Otsu 方法的原…...

(二)原型模式

原型的功能是将一个已经存在的对象作为源目标,其余对象都是通过这个源目标创建。发挥复制的作用就是原型模式的核心思想。 一、源型模式的定义 原型模式是指第二次创建对象可以通过复制已经存在的原型对象来实现,忽略对象创建过程中的其它细节。 📌 核心特点: 避免重复初…...

sqlserver 根据指定字符 解析拼接字符串

DECLARE LotNo NVARCHAR(50)A,B,C DECLARE xml XML ( SELECT <x> REPLACE(LotNo, ,, </x><x>) </x> ) DECLARE ErrorCode NVARCHAR(50) -- 提取 XML 中的值 SELECT value x.value(., VARCHAR(MAX))…...

Axios请求超时重发机制

Axios 超时重新请求实现方案 在 Axios 中实现超时重新请求可以通过以下几种方式&#xff1a; 1. 使用拦截器实现自动重试 import axios from axios;// 创建axios实例 const instance axios.create();// 设置超时时间 instance.defaults.timeout 5000;// 最大重试次数 cons…...

【数据分析】R版IntelliGenes用于生物标志物发现的可解释机器学习

禁止商业或二改转载&#xff0c;仅供自学使用&#xff0c;侵权必究&#xff0c;如需截取部分内容请后台联系作者! 文章目录 介绍流程步骤1. 输入数据2. 特征选择3. 模型训练4. I-Genes 评分计算5. 输出结果 IntelliGenesR 安装包1. 特征选择2. 模型训练和评估3. I-Genes 评分计…...

安宝特方案丨船舶智造的“AR+AI+作业标准化管理解决方案”(装配)

船舶制造装配管理现状&#xff1a;装配工作依赖人工经验&#xff0c;装配工人凭借长期实践积累的操作技巧完成零部件组装。企业通常制定了装配作业指导书&#xff0c;但在实际执行中&#xff0c;工人对指导书的理解和遵循程度参差不齐。 船舶装配过程中的挑战与需求 挑战 (1…...