定义重复字符串是由两个相同的字符串首尾拼接而成。例如:"abcabc" 是一个长度为 6 的重复字符串,因为它由两个 "abc" 串拼接而成;"abcba" 不是重复字符串,因为它不能由两个相同的字符串拼接而成。
给定一个字符串,请返回其最长重复子串的长度。
若不存在任何重复字符子串,则返回 0。
本题中子串的定义是字符串中一段连续的区间。
数据范围:字符串长度不大于 ,保证字符串一定由小写字母构成。
进阶:空间复杂度 ,时间复杂度
"ababc"
4
abab为最长的重复字符子串,长度为4
"abcab"
0
该字符串没有重复字符子串
# @param a string字符串 待计算字符串 # @return int整型 # class Solution: def solve(self , a: str) -> int: # write code here length = len(a)//2 flag = False while(not flag and length != 0): for i in range(0,len(a)-length): if(a[i:i+length] == a[i+length:i+2*length]): flag = True return 2*length length -= 1 return 0
import java.util.*; public class Solution { /** * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可 * * @param a string字符串 待计算字符串 * @return int整型 */ public int solve (String a) { // write code here int l=a.length()/2; for(;l>0;l--){ Loop:for(int i=0;i+2*l<=a.length();i++){ /*if(a.charAt(i)==a.charAt(i+l)){ if(a.substring(i,i+l).equals(a.substring(i+l,i+2*l))){ return l*2; } }*/ for(int j=i;j<i+l;j++){ if(a.charAt(j)!=a.charAt(j+l)){ continue Loop; } } return l*2; } } return 0; } }
import java.util.*; public class Solution { /** * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可 * * @param a string字符串 待计算字符串 * @return int整型 */ public int solve (String a) { // write code here int maxLen = 0; for(int i = 0; i < a.length(); i++){ for(int j = i + 2; j < a.length() + 1; j+=2){ // 求字串的时候字串长度依次加2 因为重复的一定是偶数长度 StringBuilder sb = new StringBuilder(a.substring(i,j)); int halfIndex = sb.length() / 2; if(sb.substring(0,halfIndex).equals(sb.substring(halfIndex,sb.length())) && sb.length() > maxLen){ maxLen = sb.length(); } } } return maxLen; } }
class Solution { public: //分字符串长度奇偶性讨论,模拟两个滑动窗口,一开始的最大长度是字符串的一半,从左往右滑动比较 //右端窗口滑到字符串末尾后,两个窗口长度同时减一,并从字符串左端从头开始扫描 //只要扫描过程中第一次匹配到两个窗口内的字符串相同,那么答案就是2*窗口长度 int solve(string a) { if(a.size()%2==0){//字符串长度是偶数 int l1(0),r1(a.size()/2-1); int l2(a.size()/2),r2(a.size()-1); while(l1<=r1&&l2<=r2&&a.substr(l1,r1-l1+1)!=a.substr(l2,r2-l2+1)){ int wlen = r1-l1;//窗口缩小1格 l1=0,r1=l1+wlen-1,l2=r1+1,r2=l2+wlen-1; while(r2<a.size()&&a.substr(l1,r1-l1+1)!=a.substr(l2,r2-l2+1)){ l1++,r1++; l2++,r2++; } if(a.substr(l1,r1-l1+1)==a.substr(l2,r2-l2+1)) return 2*(r1-l1+1); } return 2*(r1-l1+1); } else{//字符串长度是奇数 int l1(0),r1(a.size()/2-1); int l2(a.size()/2),r2(a.size()-2); while(l1<=r1&&l2<=r2&&a.substr(l1,r1-l1+1)!=a.substr(l2,r2-l2+1)){ while(r2<a.size()&&a.substr(l1,r1-l1+1)!=a.substr(l2,r2-l2+1)){ l1++,r1++; l2++,r2++; } if(a.substr(l1,r1-l1+1)==a.substr(l2,r2-l2+1)) return 2*(r1-l1+1); int wlen = r1-l1;//窗口缩小1格 l1=0,r1=l1+wlen-1,l2=r1+1,r2=l2+wlen-1; } return 2*(r1-l1+1); } return 0; } };
public int solve(String a) { // write code here int MAX_LEN = 0, left = 0; while (left < a.length()) { for (int right = left + 1; right < a.length(); right++) { if (a.charAt(left) == a.charAt(right)) { int leftTmp = left, rightTmp = right; while (rightTmp < a.length() && leftTmp <= right && a.charAt(leftTmp) == a.charAt(rightTmp)) { leftTmp++; if (leftTmp == right) { MAX_LEN = Math.max(MAX_LEN, leftTmp - left); left = rightTmp; } rightTmp++; } } } left++; } return MAX_LEN * 2; }
public int solve (String a) { // write code here int len = a.length(), maxLen = 0; if (len == 0 ) return 0; // dp[i][j] 表示 0 ~ i 和 i+1 ~ j 的公共后缀长度 int[][] dp = new int[len][len]; // 填充dp for (int i = 0; i < len; i++) { for (int j = i + 1; j < len; j++) { // 如果两个字符相同,则判断 i ~ j 之间的 和 j 之后的是否完全一样 if (a.charAt(i) == a.charAt(j)) { // dp[i-1][j-1] 已经计算过了,这就是动态规划的优势 // i == 0 时特殊处理 dp[i][j] = i == 0 ? 1 : dp[i - 1][j - 1] + 1; // 当 j-i 之间的间隙填满时,则是有效的, if (dp[i][j] == j - i) maxLen = Math.max(maxLen, j - i); }; } } return maxLen * 2; }
public int solve (String a) { // write code here if (a.length() == 0) return 0; int mid = a.length() / 2; for (int i = mid; i >= 0; i--) { int res = 0; for (int j = 0; j < a.length() - i; j++) { if (a.charAt(j) == a.charAt(j + i)) { res++; if (res == i) return res * 2; } else res = 0; } } return 0; }总结: DP 的解法最直观最易理解,也最容易想到
import java.util.*; public class Solution { public int solve (String a) { int n = a.length(); int temp = 0; for (int len = n / 2; len >= 1; len--) { for (int startIndex = 0; startIndex < n - len; startIndex++) { if (a.charAt(startIndex) == a.charAt(startIndex + len)) { temp++; } else { temp = 0; } if (temp == len) { return len * 2; } } } return 0; } }
public int solve (String a) { // write code here int len=a.length() ,mid=len/2; while(mid>0){ // 按最大长度递减 for(int i=0;i+mid*2<=len;i++){ // 卡mid长度的两个字符串进行比较,找到即返回 if(a.substring(i,i+mid).equals(a.substring(i+mid,i+mid*2))){ return mid*2; } } mid--; } return 0; }
import java.util.*; public class Solution { /** * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可 * * @param a string字符串 待计算字符串 * @return int整型 */ public int solve (String str) { // write code here //思路:使用字符串截取来匹配 int len=str.length(); //直接来最大长度匹配,不匹配就依次减少长度 int size=len-1; while(size>=0){ for(int i=0;i<len-size;i++){ //如果从截取位置开始,后面的字符串包含截取的字符串并且是相邻的就是最大的 if(str.substring(i+size).contains(str.substring(i,i+size))&&str.substring(i+size).length()>=size&&str.substring(i+size,i+size*2).contains(str.substring(i,i+size))){ return size*2; } } size--; } return 0; } }
package main /** * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可 * * @param a string字符串 待计算字符串 * @return int整型 */ func solve( a string ) int { ans:=0 for i:=0;i<len(a);i++{ for j:=i+1;j<=len(a);j++{ tmp:=a[i:j] if len(tmp)%2==0&&check(tmp){ if len(tmp)>ans{ ans=len(tmp) } } } } return ans } func check(s string)bool{ return s[:len(s)/2]==s[len(s)/2:] }
int solve(string a) { // write code here int len = a.length(); int nMaxlen = 0; for (int i = 0; i < len; ++i) { for (int j = len; j > 0; --j) { string sub = a.substr(i, j); if (IsDub(sub)) { if (sub.length() > nMaxlen) { nMaxlen = sub.length(); } } } } return nMaxlen; } bool IsDub(string s) { int len = s.length(); if (len < 2 || len % 2 != 0) { return false; } int half = len / 2; string s1 = s.substr(0, half); string s2 = s.substr(half); return s1 == s2; }
public int solve(String a) { char[] c = a.toCharArray(); int j; int max = 0; for (int i = 0; i < c.length - 1; i++) { j = i + 1; while (j < c.length) { if (c[i] == c[j] && (2 * j - i) <= c.length && a.substring(i, j).equals(a.substring(j, 2 * j - i))) { max = Math.max(2 * (j - i), max); } j++; } } return max; }
class Solution { public: int solve(string a) { // write code here int length = a.size(); int ans = 0; for(int i = 0; i < length ; i ++) { for(int j = 1; i + j < length ; j ++) { string str = a.substr(i,j); if(str == a.substr(i + j , str.size())) { int s = str.size(); ans = max(ans, s); } else continue; } } return ans * 2; } };
# # 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可 # # # @param a string字符串 待计算字符串 # @return int整型 # class Solution: def solve(self , a: str) -> int: # write code here size = int(len(a) / 2); while size: for i in range(len(a) - 2 * size + 1): if a[i:i+size] == a[i+size:i+2*size]: return size*2 size-=1 return size
public int solve (String a) { // write code here if (a == null || a.length() < 2) { return 0; } //next数组 int[] next = getNext(a); int max = 0; for (int i = 1; i < a.length(); i += 2) { if ((i + 1) / 2 <= next[i]) { max = Math.max(max, i + 1); } } return max; }但是不对。。。