在一行上输入一个长度为
、仅由小写字母构成的字符串
。
输出一个整数,表示字符串
的最长回文子串的长度。
cdabbacc
4
在这个样例中,
是最长的回文子串。
a
1
import java.util.Scanner; // 注意类名必须为 Main, 不要有任何 package xxx 信息 public class Main { public static void main(String[] args) { Scanner in = new Scanner(System.in); // 注意 hasNext 和 hasNextLine 的区别 while (in.hasNextLine()) { // 注意 while 处理多个 case String s = in.nextLine(); System.out.println(longestPalindrome(s)); } } private static int longestPalindrome(String s) { if (s == null || s.length() == 0) { return 0; } int max = 0; for (int i = 0; i < s.length(); i++) { // 以当前字符为中心扩展(奇数长度) int len1 = expand(s, i, i); // 以当前字符和下一个字符为中心扩展(偶数长度) int len2 = expand(s, i, i+1); int longer = Math.max(len1, len2); max = Math.max(max, longer); } return max; } private static int expand(String s, int left, int right) { while (left >= 0 && right < s.length() && s.charAt(left) == s.charAt(right)) { left--; right++; } return right - left - 1; } }
import java.util.Scanner; import java.util.ArrayList; import java.util.Collections; public class Main { public static void main(String[] args) { Scanner sc = new Scanner(System.in); while (sc.hasNext()) { String str = sc.next(); ArrayList<Integer> arr = new ArrayList<>(); if (str.length() % 2 == 0) { for (int mid = 1; mid <= str.length() - 2; mid++) { int count = 0; for (int i = 0 ; i < mid ; i++) { if (str.charAt(mid - i - 1) == str.charAt(mid + i)) { count++; } else { break; } } arr.add(count); } System.out.println(2 * Collections.max(arr)); } if (str.length() % 2 == 1) { for (int mid = 1; mid < str.length() - 2; mid++) { int count = 0; for (int i = 0 ; i < mid ; i++) { if (str.charAt(mid - i - 1) == str.charAt(mid + i + 1)) { count++; } else { break; } } arr.add(count); } System.out.println(2 * Collections.max(arr) + 1); } } } }
import java.util.Scanner; // 注意类名必须为 Main, 不要有任何 package xxx 信息 public class Main { public static void main(String[] args) { Scanner in = new Scanner(System.in); String string = in.nextLine(); // 遍历每个字符串 int maxLen = 0; String loopWords = ""; for(int i = 0; i < string.length(); i++) { for(int j = i + 1; j < string.length(); j++) { String subString = string.substring(i, j); int end = j + subString.length(); if(end > string.length()) { break; } String theOtherString = string.substring(j, end); String reversedString = new StringBuilder(theOtherString).reverse().toString(); int loopWordsLen = 2 * subString.length(); if(subString.equals(reversedString) && loopWordsLen > maxLen) { maxLen = loopWordsLen; loopWords = subString + theOtherString; } } for(int j = 1; j <= i; j++) { int left = i - j; int right = i + 1 + j; if(left < 0 || right > string.length()) { break; } // abcbaaa // i = 2, j = 1: left = 1 right = 4 ls = 1,2 = b, rs = 3,4 = b // i = 2, j = 2: left = 0 right = 5 ls = 0,2 = ab, rs = 3,5 = ba // i = 2, j = 3: break; String leftStr = string.substring(left, i); String rightStr = string.substring(i + 1, right); String reversedRightStr = new StringBuilder(rightStr).reverse().toString(); if(!leftStr.equals(reversedRightStr)) { break; } int loopWordsLen = 2 * leftStr.length() + 1; if(loopWordsLen > maxLen) { maxLen = loopWordsLen; loopWords = leftStr + string.substring(i, i+1) + rightStr; } } } System.out.println(maxLen); } }
import java.util.*; public class Main { private static int m; private static int n; public static void main(String[] args) { Scanner in = new Scanner(System.in); while (in.hasNext()) { String line = in.nextLine(); char[] chars = line.toCharArray(); int maxLength = 1; int left = 0, right = 0; int n = 0; while (right < chars.length) { int length = right - left - 1; int start = left, end = right; while (start >= 0 && end < chars.length && chars[start] == chars[end]) { start--; end++; length += 2; } maxLength = Math.max(maxLength, length); if (n % 2 == 0) { right++; }else { left++; } n++; } System.out.println(maxLength); } } }动态规划有两种解法
import java.util.Scanner; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; // 注意类名必须为 Main, 不要有任何 package xxx 信息 public class Main { public static void main(String[] args) throws IOException { BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); String line = br.readLine(); int maxLen = 0; for (int i = 0; i < line.length(); i++) { for (int j = i + 1; j <= line.length(); j++) { // 回文字符串 反转后与其自身相等 String sub = line.substring(i, j); StringBuilder sb = new StringBuilder(sub); if (sub.equals(sb.reverse().toString()) && sub.length() > maxLen) { maxLen = sub.length(); } } } System.out.println(maxLen); } }
import java.util.*; // 注意类名必须为 Main, 不要有任何 package xxx 信息 public class Main { public static void main(String[] args) { Scanner in = new Scanner(System.in); // 使用双指针法,从中心点到两边扩散,注意有两种星形式的回文子串 String str = in.nextLine(); // 定义左右指针 int l; int r; // 定义集合接收回文字符的长度 ArrayList<Integer> list = new ArrayList<>(); for (int i = 0; i < str.length() - 2; i++) { // ABBA型 int len1 = 0; if (str.charAt(i) == str.charAt(i + 1)) { // 两边发散继续寻找 l = i; r = i + 1; do { len1 += 2; l--; r++; } while (r < str.length() && str.charAt(l) == str.charAt(r)); } // ABA型 不是加2 初始值是1 int len2 = 1; if (str.charAt(i) == str.charAt(i + 2)) { // 两边发散继续寻找 l = i; r = i + 2; do { len2 += 2; l--; r++; //防止数组越界异常前置判断 } while (l >= 0 && r < str.length() && str.charAt(l) == str.charAt(r)); } list.add(Math.max(len1, len2)); } System.out.println(Collections.max(list)); } }
import java.util.Scanner; // 注意类名必须为 Main, 不要有任何 package xxx 信息 public class Main { public static void main(String[] args) { Scanner in = new Scanner(System.in); String a = in.nextLine(); int max = 0; for (int i = 0; i < a.length(); i++) { for (int j = i+1; j <= a.length(); j++) { String sub = a.substring(i,j); if (isPalindrome(sub) && sub.length() > max){ max = sub.length(); } } } System.out.println(max); } private static boolean isPalindrome(String str){ StringBuilder sub = new StringBuilder(str).reverse(); if (str.equals(sub.toString())){ return true; } return false; } }
import java.util.Scanner; public class Main { public static void main(String[] args) { Scanner in = new Scanner(System.in); String line = in.nextLine(); int num = 1; // 默认回文最小长度为1(单个字符) for (int i = 0; i < line.length(); i++) { // 回文长度为偶数 int k = Math.min(i + 1, line.length() - i - 1); int idx = 0; while (k > idx) { if (line.charAt(i - idx) != line.charAt(i + 1 + idx)) { break; } idx++; } num = Math.max(num, 2 * idx); // 回文长度为奇数 k = Math.min(i, line.length() - i - 1); idx = 0; while (k > idx) { if (line.charAt(i - 1 - idx) != line.charAt(i + 1 + idx)) { break; } idx++; } num = Math.max(num, 2 * idx + 1); } System.out.println(num); } }
import java.util.*; // 注意类名必须为 Main, 不要有任何 package xxx 信息 public class Main { public static int[] p1=new int[400]; public static int[] p2=new int[400]; public static int[] p3=new int[400]; public static int[] dp=new int[400]; public static boolean check(int x,int y){ int a=p2[y]-p2[x-1]*p1[y-x+1]; int b=p3[x]-p3[y+1]*p1[y-x+1]; return a==b; } public static void main(String[] args) { Scanner in = new Scanner(System.in); // 注意 hasNext 和 hasNextLine 的区别 while (in.hasNext()) { // 注意 while 处理多个 case Arrays.fill(p2,0); Arrays.fill(p3,0); Arrays.fill(dp,0); String s=in.next(); int n=s.length(),ans=0; p1[0]=1; for(int i=1;i<=n;i++){ dp[i]=1; p1[i]=p1[i-1]*27; p2[i]=p2[i-1]*27+(s.charAt(i-1)-'a'); p3[n-i+1]=p3[n-i+2]*27+(s.charAt(n-i)-'a'); } for(int i=1;i<=n;i++){ if(i-dp[i-1]>0&&check(i-dp[i-1],i)) dp[i]=Math.max(dp[i-1]+1,dp[i]); if(i-1-dp[i-1]>0&&check(i-1-dp[i-1],i)) dp[i]=Math.max(dp[i-1]+2,dp[i]); ans=Math.max(ans,dp[i]); } System.out.println(ans); } } }
/** * ☆☆☆☆☆ * 最长回文子串 * 中心扩展 + 动态规划 + Manacher */ private static void longestPalindrome2() { Scanner in = new Scanner(System.in); while (in.hasNext()) { String s = in.nextLine(); // 字符间隔及两边插入#,方便统一中心扩展方式的两种情况:中心在元素上和中心在元素间 StringBuilder sb = new StringBuilder("#"); for (int i = 0; i < s.length(); i++) { sb.append(s.charAt(i)).append("#"); } // 数组用于存插入#后,当前元素为中心的最大回文半径(自身算1) // 最终的最大回文长度是该半径-1(该半径多出来的#,比另一边的原字符多一) int[] arr = new int[sb.length()]; // 已知的所有回文串的最右边界+1 int maxPos = 0; // 边界最右的回文串的中心 int index = 0; for (int i = 0; i < sb.length(); i++) { if (i < maxPos) { // 此处是关键,i相对index的对称位置2*index-i,直接参与计算,避免重复计算 arr[i] = Math.min(arr[2 * index - i], maxPos - i); } else { arr[i] = 1; } // 在已有基础上继续扩展判断,越界判断,以及两边字符判断 while (i - arr[i] >= 0 && i + arr[i] < sb.length() && sb.charAt(i - arr[i]) == sb.charAt(i + arr[i])) { arr[i]++; } // 更新maxpos和index if (i + arr[i] > maxPos) { maxPos = i + arr[i]; index = i; } } int max = 0; for (int i = 0; i < sb.length(); i++) { max = Math.max(max, arr[i]); } // 最长回文串的长度 System.out.println(max - 1); // 最长回文串 for (int i = 0; i < sb.length(); i++) { if (max == arr[i]) { String result = sb.substring(i - arr[i] + 1, i + arr[i]).replace("#", ""); System.out.println(result); break; } } } }
import java.util.Scanner; // 注意类名必须为 Main, 不要有任何 package xxx 信息 public class Main { public static void main(String[] args) { Scanner in = new Scanner(System.in); // 注意 hasNext 和 hasNextLine 的区别 while (in.hasNext()) { // 注意 while 处理多个 case String str = in.nextLine(); // dp[i][j]数组, 标记下标i-j是否为回文串, // 1. 单个字符肯定是回文串, dp[i][i] == true // 2. 如果i~j是回文子串,那么i+1~j-1肯定也是回文子串 String subStr = getMaxLongStr(str); System.out.println(subStr.length()); } } private static String getMaxLongStr(String str) { int begin = 0; int maxLen = 1; int len = str.length(); char[] arr = str.toCharArray(); // 定义dp数组 // 单个字符都是回文 boolean[][] dp = new boolean[len][len]; for (int i = 0; i < len; i++) { dp[i][i] = true; } // dp[i][j] 参考的是 dp[i+1][j-1] // 边界条件: (j-1) - (i+1) + 1 < 2,则不需要参考 // 整理: j - i < 3 for (int j = 1; j < len; j++) { for (int i = 0; i < j; i ++) { if (arr[i] != arr[j]) { dp[i][j] = false; } else { if (j - i < 3) { dp[i][j] = true; } else { dp[i][j] = dp[i+1][j-1]; } } // 更新最大子串 if (dp[i][j] && j - i + 1 > maxLen) { begin = i; maxLen = j - i + 1; } } } return str.substring(begin, begin+maxLen); } }
import java.util.Scanner; // 注意类名必须为 Main, 不要有任何 package xxx 信息 public class Main { public static void main(String[] args) { Scanner in = new Scanner(System.in); String s1 = in.nextLine(); in.close(); int size = s1.length(); int res = 1; for (int k = 0; k < size; k++) { res = Math.max(res, centreExtend(s1, k, k, size)); } for (int k = 0; k < size-1; k++) { if (s1.charAt(k) == s1.charAt(k+1)) { res = Math.max(res, centreExtend(s1, k, k+1, size)); } } System.out.println(res); } private static int centreExtend(String s1, int i, int j, int size) { while (i-1 >= 0 && j+1 < size && s1.charAt(i-1) == s1.charAt(j+1)) { i--; j++; } return j - i + 1; } }
import java.util.Scanner; public class Main { public static void main(String[] args) { Scanner in = new Scanner(System.in); String str = in.nextLine(); char[] ch = str.toCharArray(); int lengthMax = 0; for (int i = 0; i < str.length() - 1; i++) { // 找到一个长度为2的回文子串 if (ch[i] == ch[i + 1]) { int temp = 1; // 该次遍历最长回文串 String strMax; // 同时向该回文子串两边向外递增直至不对称 while ((i - temp) >= 0 && (i + 1 + temp) < ch.length) { if (ch[i - temp] == ch[i + 1 + temp]) { temp++; } else { break; } } // 截取temp-1时的情况,此时即当前i时最大回文字符串 strMax = str.substring(i - temp + 1, i + 1 + temp); if (lengthMax < strMax.length()) { lengthMax = strMax.length(); } } // 找到一个长度为3的回文子串 if (i - 1 >= 0 && ch[i - 1] == ch[i + 1]) { int temp = 1; // 该次遍历最长回文串 String strMax; // 同时向该回文子串两边向外递增直至不对称 while ((i - 1 - temp) >= 0 && (i + 1 + temp) < ch.length) { if (ch[i - 1 - temp] == ch[i + 1 + temp]) { temp++; } else { // 外扩后左右字符不同时 break; } } // 截取temp-1时的情况,此时即当前i时最大回文字符串 strMax = str.substring(i - 1 - temp + 1, i + 1 + temp); // 找所有最大情况 if (lengthMax < strMax.length()) { lengthMax = strMax.length(); } } } System.out.println(lengthMax); } }
求出所有的子字符串,再利用子字符串比较,简单易懂
import java.io.BufferedReader; import java.io.IOException; import java.util.*; import java.util.ArrayList; public class Main { public static void main(String[] args) throws IOException { Scanner scan = new Scanner(System.in); String str = scan.next(); if(str.length()==0){ System.out.print(0); return; } StringBuilder stb = new StringBuilder(str); String temp = stb.reverse().toString(); int max = 1; int len = str.length(); ArrayList <String> arr = new ArrayList<String>(); for(int i=0;i<len-1;i++){ for(int j=i;j<=len;j++){ arr.add(str.substring(i,j)); } } for(int i=0;i<arr.size();i++){ String ss =arr.get(i); if(ss.equals(new StringBuilder(ss).reverse().toString())){ if(max< ss.length()) max = ss.length(); } } System.out.print(max); } }