Longest Palindromic Substring 最长回文字符串

本文介绍了两种解决寻找最长回文子串问题的方法:动态规划和Manacher算法。动态规划通过状态转移方程解决,而Manacher算法则利用预处理优化搜索过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Given a string S, find the longest palindromic substring in S. You may assume that the maximum length of S is 1000, and there exists one unique longest palindromic substring.

1、动态规划

class Solution {
public:
    string longestPalindrome(string s) {
        if(s == "" || s.length()==0)
            return "";
        int len = s.length();
        
        bool flag[len][len];
        string res = "";
        int start = 0;
        int maxLen = 0;
        for(int i=len-1;i>=0;i--)
        {
            for(int j=i;j<len;j++)
            {
                if(s[i]==s[j] && (j-i<=2 || flag[i+1][j-1]))
                {
                    flag[i][j] = true;
                    if(maxLen<j-i+1)
                    {
                        maxLen=j-i+1;
                        start = i;
                        //res = s.substr(i,maxLen);
                    }
                }else{
                    flag[i][j] = false;
                }
            }
        }
        return s.substr(start,maxLen);
    }    
};

2、Manacher算法处理字符串回文

class Solution {
public:
    string longestPalindrome(string s) {
		string t = "$";
		for (char ch : s) {
			t += '#';
			t += ch;
		}
		t += '#';
		int len = t.length();
		// t为处理过的字符串,p为记录长度的数组 
        int p[t.length()];
		// mx为已判断回文串最右边位置,id为中间位置,mmax记录p数组中最大值  
		int mx = 0, id = 0, mmax = 0;  
		int right = 0;
		for (int i = 1; i < len; i++) {  
			p[i] = mx > i ? min(p[2 * id - i], mx - i) : 1;  
			while (t[i + p[i]] == t[i - p[i]])  
				p[i]++;  
			if (i + p[i] > mx) {  
				mx = i + p[i];  
				id = i;  
			}  
			if (mmax < p[i]) {
				mmax = p[i]; 
				right = i;
			}
		}  
		// 最长为mmax - 1  
		return s.substr(right/2 - mmax/2, mmax-1);
    }
    
    
};


相关文章:http://blog.youkuaiyun.com/pi9nc/article/details/9251455

### 蓝桥杯竞赛中回文字符串题目解题思路 #### 寻找最长回文子串 对于蓝桥杯1225——最长回文子串问题,采用暴力枚举的方法可以解决问题。通过双层循环遍历所有可能的子串组合,并逐一验证其是否构成回文结构[^1]。 ```python def is_palindrome(s): return s == s[::-1] def longest_palindromic_substring(text): max_length = 0 start_index = 0 for i in range(len(text)): for j in range(i, len(text)): substring = text[i:j+1] if is_palindrome(substring) and len(substring) > max_length: max_length = len(substring) start_index = i return text[start_index:start_index + max_length] ``` 此方法虽然直观易懂,但在处理较长字符串时效率较低,时间复杂度达到O(n^3),其中n代表字符串长度。 #### 构造最长回文串并考虑字典序最小化 针对特定条件下的构建最长回文串需求,如2023华为OD机试题所示,除了关注如何形成最大长度外还需兼顾字符排列顺序以满足字典序的要求[^2]。这里介绍一种基于贪心算法的思想来解决这个问题: - 统计各个字符出现次数; - 尽量多放置成对存在的相同字符于两侧; - 如果存在奇数次出现的字符,则可将其置于中心位置; - 对剩余未配对单个字符按升序加入到中间部分之前或之后,从而保证整体形成的回文串具有较小的字典序。 实现上述逻辑如下: ```python from collections import Counter def construct_longest_palindrome(s): char_counts = Counter(s.lower()) # 不区分大小写统计频率 palindrome_parts = [] center_char = '' for char, count in sorted(char_counts.items()): pairs_count = count // 2 * 2 if pairs_count > 0: palindrome_parts.append((char * (pairs_count // 2))) if count % 2 != 0 and not center_char: center_char = char result = ''.join(palindrome_parts) + center_char + ''.join(reversed(palindrome_parts)) return result.upper() # 返回大写的最终结果 ``` 该方案能够有效地找到符合条件的最大长度且回文串的同时保持尽可能低的字典序。 #### 计算不同类型的回文数量 当涉及到计算某个范围内不同类型(比如普通型、特殊模式等)的回文数目时,可以通过动态规划或者滑动窗口技术来进行优化求解。例如,在剑指Offer第20题里提到的任务就是典型的应用场景之一[^3]。 为了提高性能表现,建议预先设定好边界情况以及初始化必要的辅助数组用于存储临时状态信息;接着逐步扩大考察范围直至覆盖整个待分析序列为止。 综上所述,面对不同的回文类编程挑战,可以根据具体要求选用合适的数据结构与算法策略加以应对。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值