给定一个仅包含小写字母的字符串,求它的最长回文子串的长度。
所谓回文串,指左右对称的字符串。
所谓子串,指一个字符串删掉其部分前缀和后缀(也可以不删)的字符串
数据范围:字符串长度
进阶:时间复杂度:,空间复杂度:
#include <bits/stdc++.h> using namespace std; int longestPalindrome(string s) { int left = 0,right = 0,len = 0; int n=s.size(); vector<vector<int> > dp(n,vector<int>(n,0)); for(int i=0;i<s.size();i++) { dp[i][i]=1; for(int j=0;j<i;j++) { dp[j][i] = (s[i]==s[j] &&(i-j<2 || dp[j+1][i-1])); if(dp[j][i] && len<i-j+1) { len = i-j+1; left=j; right=i; } } } int res=right-left+1; return res; } int main() { string s; while(cin>>s) { int res=0; res=longestPalindrome(s); cout<<res<<endl; } }
import java.io.BufferedReader; import java.io.InputStreamReader; import java.io.IOException; public class Main { public static void main(String[] args) throws IOException { BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); String str = br.readLine().trim(); int n = str.length(); for(int len = n; len >= 1 ; len --){ for(int start = 0; start <= n - len; start ++){ if(isPalindrome(str.substring(start, start + len))){ System.out.println(len); return; } } } System.out.println(1); } private static boolean isPalindrome(String str) { int left = 0, right = str.length() - 1; while(left < right){ if(str.charAt(left) != str.charAt(right)) return false; left ++; right --; } return true; } }
#include<iostream> #include<vector> #include<string> #include<algorithm> using namespace std; string findLongestPalindromeManacher(const string s){ string s1("^#"); for (auto ch : s){ s1 += ch; s1 += '#'; } s1 += '$'; vector<int>pv(s1.length(), 0);//记录回文半径 int index(0), mlen(1); for (int k1 = 2, mid = 1, mxr = 0; k1 < s1.length(); ++k1){ pv[k1] = k1 < mxr ? min(pv[mid * 2 - k1], mxr - k1) : 1; while (s1[k1 + pv[k1]] == s1[k1 - pv[k1]]){ ++pv[k1];//回文半径增加 } if (mxr < mid + pv[k1]){ mxr = mid + pv[k1]; mid = k1; } if (mlen < pv[k1]){ mlen = pv[k1]; index = k1; } } return s.substr((index - mlen) / 2, mlen - 1); } int main(){ string s; while (cin>>s) { string s1 = findLongestPalindromeManacher(s); cout << s1.length() << endl; } return 0; }
int main(){ string str; while(cin >> str) { vector<vector<int>>dp(str.size(), vector<int>(str.size())); int ans = 1; for(int i = 0; i < str.size(); ++i) { dp[i][i] = 1; if(i < str.size() - 1) { if(str[i] == str[i+1]) { dp[i][i+1] = 1; ans = 2; } } } for(int L = 3; L <= str.size(); ++L) for(int i = 0; i + L - 1 < str.size(); ++i) { int j = i + L -1; if(str[i] == str[j] && dp[i+1][j-1]) { dp[i][j] = 1; ans = L; } } cout << ans << endl; } }
function toManacherString(str) { let a = ['#']; for (let i=0;i<str.length;i++) { a.push(str[i]); a.push('#'); } return a; } function manacher(str) { let a = toManacherString(str); let ra = Array(a.length).fill(0); let c = -1, r = -1; let max = Number.MIN_SAFE_INTEGER; debugger; for (let i = 0; i < a.length; i++) { if (r > i) { let pl = 2 * c - i; if (pl - ra[pl] > c - r) { ra[i] = ra[pl]; continue; } else if (pl - ra[pl] < c - r) { ra[i] = r - i + 1; continue; } else { ra[i] = r - i + 1; } } while (i + ra[i] < ra.length && i - ra[i] > -1) { if (a[i + ra[i]] === a[i - ra[i]]) { ra[i]++; } else { break; } } if (i + ra[i] > r) { r = i + ra[i] - 1; c = i; } if (ra[i] > max) { max = ra[i]; } } return max - 1; } let input =readline(); print(manacher(input))
import java.util.Scanner; public class Main{ public static int lenRoundStr(String s, int left, int right){ while(left>=0 && right<s.length() && s.charAt(left) == s.charAt(right)){ left--; right++; } return right-left-1; } public static void main(String[] args){ Scanner sc = new Scanner(System.in); String inp = sc.nextLine(); int maxlen = Integer.MIN_VALUE; for(int i=0; i<inp.length()-1; i++){ int ans = Math.max(lenRoundStr(inp,i,i), lenRoundStr(inp,i,i+1)); maxlen = Math.max(ans, maxlen); } System.out.println(maxlen); } }
import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; public class Main { public static void main(String[] args) throws IOException { BufferedReader br=new BufferedReader(new InputStreamReader(System.in)); String str; while ((str=br.readLine())!=null){ int len=str.length(); int max=0; int temp; for(int i=0;i<len;i++){ //去掉不需要的处理 if(max%2==1){ if((len-i)<((max/2)+1)){ break; } }else { if((len-i)<(max/2)){ break; } } temp=0; //奇数 if(i+2<len && str.charAt(i)==str.charAt(i+2)){ temp++; int left=i-1; int right=i+3; while (left>=0 && right<len) { if(str.charAt(left)==str.charAt(right)){ temp++; left--; right++; }else { break; } } max=Math.max(max,temp*2+1); } //偶数 //必须对temp进行重置 temp=0; if(i+1<len && str.charAt(i)==str.charAt(i+1)){ temp++; int left=i-1; int right=i+2; while (left>=0 && right<len) { if(str.charAt(left)==str.charAt(right)){ temp++; left--; right++; }else { break; } } max=Math.max(max,temp*2); } } System.out.println(max); } } }
def longestPalindrome( s: str) -> str: if not s: return "" n = len(s) res=[] for i in range(1, n): # 中轴情况 j = 1 while i - j >= 0 and i + j <= n-1 and s[i - j] == s[i + j]: j += 1 j-=1 num=j*2+1 res.append(num) # 对称情况 j = 1 while i - j >=0 and i + j - 1 <= n-1 and s[i - j] == s[i + j - 1]: j += 1 j-=1 num=j*2 res.append(num) num=max(res) return num while True: try: s=input() print(longestPalindrome(s)) except: break
//N为字符串长度,i为定位器,其作用是寻找最长回文子串的中心,left和right //是从i左端(或自身)和右段延申出去的定位器,最终是最长回文字串左端减一和右端加一的位置。可以看到我把代码复制了两次,其中的不同就在于 //for循环中的left=i和left=i-1,这是因为最长回文字串有可能是偶数或者奇数个,此时i可能是X.5,或者X,(X为最长回文子串中心的位置) //此外,本题如果出现了段越界,就是你先前定义的数组不够大的原因,一开始我定义了100个都不够用 #include <stdio.h> #include <string.h> int main( ) { char a[1000]; int N=0,i=1,left,right,lenth; while(scanf("%s",a)!=EOF){ //printf("%s",a); N=strlen(a);lenth=0; for(i=0;i<N;i++) {left=i,right=i+1; while(left>=0&&right<N&&a[left]==a[right]) { left--; right++; } if(right-left-1>lenth) { lenth=right-left-1; } } for(i=0;i<N;i++) {left=i-1,right=i+1; while(left>=0&&right<N&&a[left]==a[right]) { left--; right++; } if(right-left-1>lenth) { lenth=right-left-1; } } printf("%d\n",lenth); } return 0; }
#include <iostream> using namespace std; int main() { string str; while ( cin >> str ) { int len = str.size(); bool dp[len][len];//字符串i到j区间是否为回文子串 for (int i=0;i<len;i++) { for (int j=0;j<len;j++) { dp[i][j] = false; } } for (int i=0;i<len;i++) { dp[i][i] = true; } int imax=0; for (int j=1;j<len;j++) { for (int i=0;i<=j;i++) { if (str[i] == str[j]) { if (j-i<3) { dp[i][j] = true; } else { dp[i][j] = dp[i+1][j-1]; } if (dp[i][j]) { imax = imax > (j-i+1) ? imax : (j-i+1); } } } } cout << imax <<endl; } return 0; }
#include<stdio.h> #include<string.h> #define N 1024 int main() { char str[N]; while (scanf("%s",str)!=EOF){ int n= strlen(str); int i,k,sum,max; max=0; for (i=0;i<n;i++) { sum=0; if(str[i]==str[i+1]) { for(k=0;k<n;k++) {if(str[i-k]==str[i+k+1]) { sum=sum+1; } else if(str[i-k]!=str[i+k]) break;} } if (max<sum) max=sum; } printf("%d",max*2); } return 0; }
#include <stdio.h> int main(void) { char string[1000]; int idx = 0; int right = 0; int left = 0; int cnt = 0; int maxCnt = 0; while (EOF != scanf("%s", string)) { idx = 0; maxCnt = 0; cnt = 0; while (string[idx++] != '\0') { if (idx > 0 && string[idx] == string[idx - 1]) { cnt = 2; left = idx - 1; right = idx; } else if (idx > 1 && string[idx] == string[idx - 2]) { cnt = 3; left = idx - 2; right = idx; } while (left > 0 && string[right + 1] != '\0' && string[++right] == string[--left]) { cnt += 2; } if (cnt > maxCnt) maxCnt = cnt; cnt = 0; } printf("%d\n", maxCnt); } }非常利于理解的解法
#include <bits/stdc++.h> using namespace std; int checkSubstrValid(const string &input, int len, int left, int right) { bool isOdd = (left == right); int res; if (isOdd) { res = 1; --left; ++right; } else { res = 0; } for (; left >= 0 && right < len; --left, ++right) { if (input[left] == input[right]) { res += 2; } else { break; } } //cout << res << endl; return res; } int getMaxHuiwen(const string &input) { uint32_t n = input.length(); if (n == 0 || n == 1) { return n; } int maxLen = 0; for (uint32_t i = 0; i < n-1; ++i) { maxLen = max(maxLen, checkSubstrValid(input, n, i, i)); maxLen = max(maxLen, checkSubstrValid(input, n, i, i+1)); } return maxLen; } int main () { string input; while (getline(cin, input)) { int res = getMaxHuiwen(input); if (res) { cout << getMaxHuiwen(input) << endl; } } return 0; }
//package june.code.byhehe.forOffer.HW; import java.util.Scanner; /** * 华为HJ85 * 因为截获的串太长了,而且存在多种可能的情况(abaaab可看作是aba,或baaab的加密形式),Cathcer的工作量实在是太大了,他只能向电脑高手求助,你能帮Catcher找出最长的有效密码串吗? * * (注意:记得加上while处理多个测试用例) */ public class Main { public static void main(String[] args) { Scanner sc = new Scanner(System.in); while (sc.hasNext()){ String s = sc.nextLine().trim(); // 以 i 和 i+1 为中心扩展 String res=""; for (int i = 0; i < s.length(); i++) { String s1 = getHuiWen(s, i, i); String s2 = getHuiWen(s, i, i+1); res = res.length()>s1.length()?res:s1; res = res.length()>s2.length()?res:s2; } System.out.println(res.length()); } } public static String getHuiWen(String s, int l, int r){ while (l>=0 && r < s.length() && s.charAt(l) == s.charAt(r)){ l--; r++; } return (r-l) == 1?s.substring(l,r):s.substring(l+1, r); } }
package huaweitest; import java.util.Scanner; public class Main18 { public static void main(String[] args) { Scanner cin = new Scanner(System.in); while (cin.hasNext()) { String s = cin.nextLine(); int flag = 0, max = 0; //长度从最长开始 for (int k = s.length(); k >= 1; k--) { int i = 0; //注意判断条件 while (i + k <= s.length()) { if (check(s.substring(i, i + k))) { flag = 1; max = k; break; } i++; } if (flag == 1) { break; } } System.out.println(max); } } public static boolean check(String s) { int i = 0, j = s.length() - 1; while (i < j) { if (s.charAt(i) != s.charAt(j)) return false; i++; j--; } return true; } }
while True: try: a = raw_input() m = len(a) dp = [[0]*m for _ in range(m)] ans = [] for x in range(m): for y in range(m-x): i = y j = x + y if a[i] != a[j]: dp[i][j] = 0 else: if j-i == 0: dp[i][j] = 1 elif j-i == 1: dp[i][j] = 2 else: if dp[i+1][j-1] == 0: dp[i][j] = 0 else: dp[i][j] = dp[i+1][j-1] + 2 for i in dp: ans.append(max(i)) print max(ans) except: break