zoukankan      html  css  js  c++  java
  • Manacher算法解决最长回文子串长度问题

    马拉车(Manacher)算法(具体算法流程看这个哥们的:https://blog.csdn.net/qq_35065720/article/details/104205920):

    算法解决:在一个字符串中找到最长的回文字符串。
    实现策略: 
    以每个位置作为中心,向两边扩展,可以确定奇回文,但是偶回文无法这样做。
    解决方法:在字符串中间及两边插入某种字符,此时可以按照这种方法进行扩展。此时无论奇回文还是偶回文都可以找到。
    例如11211,此时添加任意字符在两边#1#1#2#1#1#此时均可以进行回文判断。
     
    C++代码实现:
    class Solution1 {
    public: 
    	char* manacherString(string str) {
    		char* charArr = new char[str.size() * 2 + 1];
    		int str_len = str.size();
    		for (int i = 1; i <= str_len; i++) {
    			charArr[2 * i] = str[i - 1];
    			charArr[2 * i + 1] = '#';
    		}
    		return charArr;
    	}
    
    	int maxLcpsLength(string str) {
    		if (str.size() == 0) {
    			return 0;
    		}
    		char* charArr = manacherString(str);
    		vector<int> pArr(strlen(charArr)); // 回文半径数组
    		int C = -1;
    		int R = -1;
    		int max_val = INT_MIN;
    		for (int i = 0; i != strlen(charArr); i++) {
    			pArr[i] = R > i ? min(pArr[2 * C - i], R - i) : 1;
    			// R > i 表示 i在回文右边界里面,有一个不用验的区域
    			//  2*C-i 为 i关于C的对称点i',两个瓶颈:1.i'的回文半径 2. R到我(i)的距离
    			while (i + pArr[i] < strlen(charArr) && 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_val = max(max_val, pArr[i]); // 全局最大值
    		}
    		return max_val - 1;
    	}
    };
    

      

     
     
  • 相关阅读:
    python基础学习文件内容的操作
    python基础学习字符串操作
    python基础学习运算符
    python基础学习列表
    centos一键安装nginx
    centos6添加整段多IP脚本
    Ubuntu 添加整段多IP脚本
    安装python2.7
    两位float型的小数相加,不会变成两位小时的处理方法
    mysql 5.7 执行group by 语句报错
  • 原文地址:https://www.cnblogs.com/E-Dreamer-Blogs/p/12642756.html
Copyright © 2011-2022 走看看