在一行上输入一个长度为
,仅由大小写字母和数字构成的字符串
,代表截获的密码。
在一行上输出一个整数,代表最长的有效密码串的长度。
ABBA
4
在这个样例中,没有无关字符,所以最长的有效密码串就是
本身,长度为
。
12HHHHA
4
在这个样例中,最长的有效密码串是
,长度为
。
/*
https://ethsonliu.com/2018/04/manacher.html
https://leetcode.wang/leetCode-5-Longest-Palindromic-Substring.html#
左程云算法讲解视频
https://www.bilibili.com/video/BV13g41157hK?p=13
位置1:30分
*/
import java.util.Scanner;
public class Main {
// 字符串预处理
public static char[] manacherString(String str) {
char[] chars = str.toCharArray();
char[] res = new char[str.length() * 2 + 1];
int index = 0;
for (int i = 0; i < res.length; i++) {
if (i % 2 == 0) {
res[i] = '#';
} else {
res[i] = chars[index];
index++;
}
}
return res;
}
public static int manacher2(String str) {
if (str == null || str.length() == 0) {
return 0;
}
char[] s = manacherString(str);
int[] p = new int[s.length];
int C = 0;
int R = 0;
int maxLen = Integer.MIN_VALUE;
for (int i = 0; i < s.length; i++) {
int iMirror = 2 * C - i;
if (i < R) {
p[i] = Math.min(p[iMirror], R - i);
} else {
p[i] = 1;
}
while (i + p[i] < s.length && i - p[i] >= 0) {
if (s[i + p[i]] == s[i - p[i]]) {
p[i]++;
} else {
break;
}
}
if (i + p[i] > R) {
R = i + p[i];
C = i;
}
maxLen = Math.max(maxLen, p[i]);
}
return maxLen - 1;
}
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
while(sc.hasNext()){
String str = sc.nextLine();
System.out.println(manacher2(str));
}
}
} 刚理解这个算法,过几天再复习一遍,看能不能写出来
import java.util.*;
public class Main{
public static void main(String[] args){
Scanner input = new Scanner(System.in);
while(input.hasNext()){
String s = input.nextLine();
if(s == null || s.equals("")){
break;
}
int result = 1;
for(int i = 0;i<s.length();i++){
int max1 = calMaxStr(s, s.split(""),i,i);
int max2 = calMaxStr(s, s.split(""),i,i + 1);
result = Math.max(max1, result);
result = Math.max(max2, result);
}
System.out.println(result);
}
}
// 计算最长回文子串的长度公共方法
public static Integer calMaxStr(String s, String[] sArray,int l, int r){
while(l >= 0 && r < sArray.length && sArray[l].equals(sArray[r])){
l--;
r++;
}
return r-l-1;
}
} import java.util.Scanner;
/**
* @author Yuliang.Lee
* @version 1.0
* @date 2021/9/9 10:40
* 最长的对称字符串:
比如像这些ABBA,ABA,A,123321,称为对称字符串,定义为有效密码。
输入一个字符串,返回有效密码串的最大长度。
* 示例:
输入1:1kABBA21
输出1:4
输入2:abaaab
输出2:5
*/
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
while (in.hasNext()) {
String pswd = in.nextLine();
int maxValid = 0;
for (int n = pswd.length(); n > 0; n--) {
if (hasValidWithinLen(pswd, n)) {
maxValid = n;
break;
}
}
System.out.println(maxValid);
}
}
// 判断是否存在长度为len的对称字符串
public static boolean hasValidWithinLen(String password, int len) {
for (int i = 0; i + len - 1 < password.length(); i++) {
int left = i;
int right = i + len - 1;
while (left < right) {
// 指针从最左侧最右侧的字符往中间对称轴靠,如果当中有任意一对左右字符不相等则结束本次对称判断
if (password.charAt(left) != password.charAt(right)) {
break;
}
left++;
right--;
}
if (left >= right) {
return true;
}
}
return false;
}
}
import java.util.*;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
while(sc.hasNext()){
String s = sc.next();
int ans = 0;
for(int i=0;i<s.length();i++){
int res = Math.max(lengths(s,i,i+1,0)*2,(lengths(s,i,i,0)-1)*2+1);
ans = Math.max(ans,res);
}
System.out.println(ans);
}
sc.close();
}
private static int lengths(String s,int start,int end,int count){
while(start>=0&&end<s.length()&&s.charAt(start)==s.charAt(end)){
count++;
start--;
end++;
}
return count;
}
}
#include <iostream>
#include <string>
#include <vector>
using namespace std;
int main() {
string str;
while (getline(cin, str)) {
int max = 1;
for (int i = 0; i < str.size(); i++) {
int count = 0;
for (int left = i - 1, right = i + 1; left >= 0 && right < str.size(); left--, right++) {
if (str[left] == str[right]) {
count++;
if (max < (2 * count + 1)) max = 2 * count + 1;
}
else break;
}
}
for (int i = 0; i < str.size() - 1; i++) {
int count = 0;
for (int left = i, right = i + 1; left >= 0 && right < str.size(); left--, right++) {
if (str[left] == str[right]) {
count++;
if (max < (2 * count)) max = 2 * count;
}
else break;
}
}
cout << max << endl;
}
return 0;
}
// 最长回文子串
import java.util.*;
public class Main{
public static void main(String[] args){
Scanner sc=new Scanner(System.in);
while(sc.hasNext()){
String st=sc.next();
int maxLen=0;
for(int i=1;i<st.length()-1;i++){
int j=0;
for(j=1;i-j>=0 && i+j<st.length();j++){
if(st.charAt(i-j)!=st.charAt(i+j))
break;
}
maxLen=Math.max(maxLen,2*j-1);
if(st.charAt(i)==st.charAt(i+1)){
for(j=1;i-j>=0 && i+1+j<st.length();j++){
if(st.charAt(i-j)!=st.charAt(i+1+j))
break;
}
maxLen=Math.max(maxLen,2*j);
}
}
System.out.println(maxLen);
}
}
} //同楼上一位答主一样,以每个字符(奇数长度的回文串)或者字符间空隙
//(偶数长度的回文串)分别向左向右扩充,记录遇到的最大长度
import java.util.Scanner;
public class Main{
public static int process(String str){
int len=str.length();
if(len<1){
return 0;
}
int max=1;//只要字符创长度大于1,则最短的回文串长度为1
//考虑奇数个数的回文串
for(int i=1;i<len-1;i++){
int k=i-1,j=i+1;
int count=0;
while(k>=0 && j<=len-1){
if(str.charAt(k--)==str.charAt(j++)){
count++;
}else{
break;
}
}
max= (max>=(count*2+1)) ? max:(count*2+1);
}
//现在考虑偶数回文串的情况,主要考虑字符之间的位置
for(int i=1;i<len-1;i++){
int k=i-1,j=i;
int count=0;
while(k>=0 && j<=len-1){
if(str.charAt(k--)==str.charAt(j++)){
count++;
}else{
break;
}
}
max= (max>=count*2) ? max : (count*2);
}
return max;
}
public static void main(String[] args){
Scanner in=new Scanner(System.in);
while(in.hasNext()){
String str=in.next();
System.out.println(process(str));
}
in.close();
}
}
s = input() n = len(s) dp = [[0 for _ in range(n)]for _ in range(n)] dp[n-1][n-1]=1 for i in range(n-1): dp[i][i]=1 dp[i][i+1] = 2 if s[i]==s[i+1] else 1 for L in range(n-3,-1,-1): for R in range(L+2,n): temp = s[L:R+1] dp[L][R] = max(dp[L+1][R],dp[L][R-1]) if temp==temp[::-1]: dp[L][R]=max(dp[L][R],len(temp)) print(dp[0][n-1])
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 pw = sc.nextLine();
int maxValue = Integer.MIN_VALUE;
for(int i=0; i<pw.length()-1; i++){
int ans = Math.max(lenRoundStr(pw, i, i), lenRoundStr(pw, i, i+1));
maxValue = Math.max(ans, maxValue);
}
maxValue = Math.max(lenRoundStr(pw, pw.length()-1, pw.length()-1), maxValue);
System.out.println(maxValue);
}
} #include<iostream>
#include<string>
#include<vector>
using namespace std;
int main(){
string s;
while(cin>>s){
int n=s.size();
//求最长回文子串
vector<vector<bool>> dp(n,vector<bool>(n,false));
for(int i=0;i<n;i++){
dp[i][i]=true;
}
int ans=0;
for(int i=n-2;i>=0;i--){
for(int j=i+1;j<n;j++){
if(s[i]==s[j]){
if(j-i>2){
if(dp[i+1][j-1]){
dp[i][j]=true;
ans=max(ans,j-i+1);
}
}else{
dp[i][j]=true;
ans=max(ans,j-i+1);
}
}
}
}
cout<<ans<<endl;
}
return 0;
} //中心扩散算法
import java.util.Scanner;
public class Main{
public static void main(String[] args){
Scanner sc = new Scanner(System.in);
while(sc.hasNext()){
String s = sc.nextLine();
int ans = maxLen(s);
System.out.println(ans);
}
}
private static int maxLen(String s){
if(s==null || s.length()==0) return 0;
if(s.length()==1) return 1;
int max = 0;
int len = s.length();
for(int i=0; i<s.length(); i++){
int cur = 1;
int left=i-1, right=i+1;
while(left>=0 && s.charAt(left)==s.charAt(i)){//左边相同移动
left--;
cur++;
}
while(right<len && s.charAt(right)==s.charAt(i)){//右边相同移动
right++;
cur++;
}
while(left>=0 && right<len && s.charAt(left)==s.charAt(right)){//两边同时相同移动
left--;
right++;
cur += 2;
}
if(cur>max) max = cur;
}
return max;
}
} public static void main(String[] args){
Scanner in = new Scanner(System.in);
while(in.hasNext()){
String str = in.next();
int len = str.length();
if(len < 1){
System.out.println(0);
continue;
}
boolean[][] dp = new boolean[len][len];
int maxLen = 1;
for(int j = 0;j < len;j++){
for(int i = 0;i <= j;i++){
if(str.charAt(i) == str.charAt(j)){
if(j - i < 3){
dp[i][j] = true;
}else{
dp[i][j] = dp[i + 1][j - 1];
}
}else{
dp[i][j] = false;
}
if(dp[i][j]){//更新最大长度
maxLen = Math.max(maxLen,j - i + 1);
}
}
}
System.out.println(maxLen);
}
} while True: try: pwd = input().strip() n = len(pwd) maxLen = 1 for i in range(1, n): # 长度为偶数 left, right = i - 1, i while left >= 0 and right < n and pwd[left] == pwd[right]: left -= 1 right += 1 maxLen = max(maxLen, right - left - 1) # 长度为奇数 left, right = i - 1, i + 1 while left >= 0 and right < n and pwd[left] == pwd[right]: left -= 1 right += 1 maxLen = max(maxLen, right - left - 1) print(maxLen) except: break
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;
while((str = br.readLine()) != null) {
int len = str.length();
while(len >= 2){
if(isPalindrome(str, len))
break;
len --;
}
System.out.println(len);
}
}
private static boolean isPalindrome(String str, int len) {
for(int start = 0; start <= str.length() - len; start++){
int left = start, right = start + len - 1;
while(left < right){
if(str.charAt(left) == str.charAt(right)){
left ++;
right --;
}else
break;
}
if(left >= right) return true;
}
return false;
}
}
# 改版 def zcHW(s): if s == s[::-1]: return len(s) s = list(s) newS = '#' + '#'.join(s) + '#' Len = len(newS) maxLen = [1] * Len # 默认自身为回文 for i in range(1,Len): # 对于索引i,前面有i个元素,索引为[0:i],后面有Len-i-1个元素,索引[i+1:Len] r = min(i, Len-i-1) # 能够达到的最大半径r m = 1 # 假设的初始半径 while m <= r: # 当前元素以半径为准,对左右两侧的元素逐一比对 if newS[i-m] == newS[i+m]: maxLen[i] = m m += 1 else: # 如果不相等了,跳出while循环,去判断下一个i break return maxLen while True: try: s = input().strip() maxLen = zcHW(s) print(max(maxLen)) except: break
#include <bits/stdc++.h>
using namespace std;
int ExpandFromCenter(string &s, int left, int righ)
{
if(left > righ)
{
return 0;
}
while(left >= 0 && righ < s.size() && s[left] == s[righ])
{
left--;
righ++;
}
return righ - left - 1;
}
int main()
{
string s;
while(cin >> s)
{
int maxlen = 0;
for(int i = 0; i < s.size() - 1; i++)
{
int len1 = ExpandFromCenter(s, i, i);
int len2 = ExpandFromCenter(s, i, i + 1);
maxlen = max(maxlen, max(len1, len2));
}
cout << maxlen << endl;
}
}