IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 数据结构与算法 -> Manacher算法 -> 正文阅读

[数据结构与算法]Manacher算法

原始问题:

在一个字符串中找到最长的回文字符串

什么是回文字符串? aba, abba。

添加任意字符在两边#1#1#2#1#1#进行回文判断。

  • 回文直径:以一个位置为中心,扩出来整个串的长度为回文直径
  • 回文半径:以一个位置为中心,扩出来半个串长度为回文半径
  • 回文数组:对于字符串而言,从0位置开始,一直到最后,新建一个数组,数组中保存对应位置的回文半径。
  • 最右回文右边界:所有回文半径中,最靠右的边界,回文右边界只要没更新,记录最早取得此处的回文中心。

Manacher算法的核心在于一个回文数组。根据具体例子来走。解题思路:

  • 回文右边界R不包含位置i,此时暴力扩展,直到R包含i。
  • i位置在回文有边界内时,知道了回文右边界可以知道回文左边界,对称中心为c,此时关于c做i的对称点i‘,若i‘的回文彻底在c为中心的回文里面,此时i的回文半径和i’的回文半径相同。
  • i位置的对称位置i’的回文半径越过了以c为中心的左边范围。(i‘扩出的范围以c为中心的回文没包住,存在一部分在回文直径外面)此时i’的回文半径是i-R。
  • 正好i‘的回文半径正好跟左边L相等,此时可以直到i的回文半径大于等于i-R,然后需要判断R后面的位置,重新返回第一步。
  • 整个算法的复杂度O(n),虽然第一步和第四步花费时间长,但是1,4都会扩展R,依次变化的过程中,R最多也就是变化到n,所以时间复杂度为O(n)。

Java代码如下:

public static char[] manacherString(String str){
	char[] charArr = str.toCharArray();
	char[] res = new char[str.length()*2+1];
	int index = 0;
	for(int i = 0;i != res.length;i++){
		res[i] = (i&1) == 0? '#':charArr[index++];
	}
	return res;
}

public static int maxLcpsLength(String str){
	if(str == null || str.length() == 0){
		return 0;
	}
	char[] charArr = manacherString(str);
	int[] pArr = new int[charArr.length];
	int C = -1;
	int R = -1;
	int max = Integer.MIN_VALUE;
	for(int i = 0;i != charArr.length;i++){
        //让至少是回文的区域加入到数组中
		pArr[i] =R > i ? Math.min(pArr[2*c-i],R-i):1;

        //左边和右边都不越界的情况下。如果相等就继续扩,如果不相对了,就退出
		while(i+pArr[i]<charArr.length && i-pArr[i]> -1 ){
			if(charArr[i +pArr[i]] == charArr[i-pArr[i]])
				pArr[i]++;
			else{
				break;
			}
		}
		if(i + pArr[i]>R){
			R = i+pArr[i];
			c = i;
		}
		max = Math.max(max,pArr[i]);
	}
	return max-1;
}

  数据结构与算法 最新文章
【力扣106】 从中序与后续遍历序列构造二叉
leetcode 322 零钱兑换
哈希的应用:海量数据处理
动态规划|最短Hamilton路径
华为机试_HJ41 称砝码【中等】【menset】【
【C与数据结构】——寒假提高每日练习Day1
基础算法——堆排序
2023王道数据结构线性表--单链表课后习题部
LeetCode 之 反转链表的一部分
【题解】lintcode必刷50题<有效的括号序列
上一篇文章      下一篇文章      查看所有文章
加:2022-03-13 22:03:13  更:2022-03-13 22:04:34 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/26 13:42:09-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码