题目描述
给定两个字符串s ss和t tt,如果存在字符串x xx使得s = x + x + . . . + x s=x+x+…+xs=x+x+…+x并且t = x + x + . . . + x t=x+x+…+xt=x+x+…+x,也就是说s ss和t tt都可以分割为某个相同字符串的拼接,那就返回最长满足条件的x xx,否则返回空串。题目要求分割出x xx的出现次数要大于等于1 11,也就是说不能分出空串。我们可以将x xx称为“最大公约串”。
解题思路
思路1: 暴力求解,从s1、s2中较短的字符串开始,依次枚举子串,看是否能同时是s1和s2的最大公约子串。
public static String gcdOfStrings(String str1, String str2) {
int len1 = str1.length(), len2 = str2.length(), len = Math.min(len1, len2);
int t = len;
while (t > 0) {
String com1 = gcdOfString(str1, t), com2 = gcdOfString(str2, t);
if (!com1.equals("") && com1.equals(com2)) {
return com1;
} else {
t--;
}
}
return "";
}
private static String gcdOfString(String s, int t) {
String tmp = s.substring(0, t);
if(tmp.equals(s)) {
return s;
}
if(s.length() % tmp.length() == 0) {
for (int i = t; i < s.length(); i += t) {
if (!tmp.equals(s.substring(i, i + t))) {
return "";
}
}
return tmp;
}
return "";
}
思路二:如果其中一个为空则直接返回空串。如果s + t ≠ t + s 也直接返回空串。
当s+t =t+s时, 然后算一下两个串长度的最大公约数l ll,则s ss的长l ll的前缀即为所求。
数学证明
class Solution {
public int gcd(int x, int y) {
if (y == 0) {
return x;
} else {
return gcd(y, x % y);
}
}
public String gcdOfStrings(String str1, String str2) {
// Check if they have non-zero GCD string.
if (!(str1 + str2).equals(str2 + str1)) {
return "";
}
// Get the GCD of the two lengths.
int gcdLength = gcd(str1.length(), str2.length());
return str1.substring(0, gcdLength);
}
}