zoukankan      html  css  js  c++  java
  • [每日一题2020.06.26]最大回文子串 manachar

    题目 :

    image-20200626190450694

    image-20200626190505662

    就是一个求最大回文子串的模板题 :

    方法一 : 中心扩展 时间复杂度(O(n^2))

    之前在leetcode上就是用的中心扩展做的, 勉强过了

    中心扩展思路很简单, 就是遍历一遍字符串, 然后对于每一个字符都向左右扩展求最大回文串

    这道题的中心扩展代码 :

    #include<bits/stdc++.h>
    using namespace std;
    const int maxn = 2000000 + 5;
    #define debug(x) 
    (void)(cerr << "L" << __LINE__
    			<< " : " << #x << " = " 
    			<< (x) << endl )
    
    
    int judge(string s) { 
    	string ss = "";
    	for (int i = 0; i < s.size(); ++i) {
    		ss += '#';
    		ss += s[i];
    	}
    	ss += '#';
    	int ptr = 0;
    	int ans = -1;
    	while (ptr < ss.size() - 1) {
    		int k = 1;
    		int sum = ( ss[ptr] == '#' ? 0 : 1 );
    		while (ptr + k < ss.size() && ptr - k >= 0 && ss[ptr + k] == ss[ptr - k])
    		{
    			sum += ( ss[ptr + k] == '#' ? 0 : 2 );
    			k++;
    		}
    		ptr++;
    		ans = max(ans, sum);
    	}
    	return ans;
    }
    
    
    
    int main() {
        ios::sync_with_stdio(false);
        cin.tie(0);
     	string s;
     	int i = 1;
     	while (cin >> s && s != "END") {
     		cout << "Case " << i++ << ": " << judge(s) << endl;
     	}   
        return 0;
    }
    

    由于时间复杂度太高, 这题TLE, 被迫学习manachar

    方法二 : manachar 时间复杂度(O(n))

    因为这个算法有点牛逼, 我直接另开一篇博客记录一下

    本质就是利用了回文串的对称性, 避免了中心扩展的许多重复操作

    #include<iostream>
    #include<string>
    #include<string.h>
    using namespace std;
    const int maxn = 2000000 + 5;
    int lens[maxn];
    
    void reIO() {
    #ifndef ROCCOSHI
    	freopen("in.txt", "r", stdin);
    	freopen("out.txt", "w", stdout);
    #endif
    }
    
    #define debug(x) 
    (void)(cerr << "L" << __LINE__
    			<< " : " << #x << " = " 
    			<< (x) << endl )
    
    string expand(string s) {
    	string ss = "$";
    	for (int i = 0; i < s.size(); ++i) {
    		ss += '#';
    		ss += s[i];
    	}
    	ss += "#^";
    	return ss;
    }
    
    
    int manachar(string s) {
    	int mx = 0;
    	int pos = 0;
    	int ans = -1;
    	for (int ptr = 1; ptr < s.size() - 1; ++ptr) {
    		if (ptr < mx) 
    			lens[ptr] = min (lens[2 * pos - ptr], mx - ptr);
    		else
    			lens[ptr] = 1;
    		while (s[ptr - lens[ptr]] == s[ptr + lens[ptr]])
    			lens[ptr]++;
    		if (mx < ptr + lens[ptr]) { 
    			mx = ptr + lens[ptr];
    			pos = ptr;
    		}
      		ans = max (ans, lens[ptr] - 1);
    	}
    	return ans;
    }
    
    
    
    int main() {
    	ios::sync_with_stdio(false);
    	cin.tie(0);
    	reIO();
    	string s;
    	int i = 1;
    	while (cin >> s && s != "END") {
    		s = expand(s);
    		cout << "Case " << i++ << ": " << manachar(s) << endl;
    	}
    	return 0;
    }
    
  • 相关阅读:
    0x00000090 该内存不能read written
    AutoCAD系统变量:EDGEMODE
    AutoCAD.net: DoubleClick
    Access 类型转换函数
    无法更改文件夹的隐藏属性 解决方法!
    Windows防火墙无法启动解决办法
    AutoCAD.net: DrawOrderChange display order of the entities in the drawing
    C#调用C++编写的COM DLL
    编辑AutoCAD 2010中新出现的CUIx文件[转]
    hook钩子
  • 原文地址:https://www.cnblogs.com/roccoshi/p/13196167.html
Copyright © 2011-2022 走看看