有两个字符串-s
和t
。
查找字符串s是否可被字符串t整除。如果可以将字符串t连接若干次以获得字符串s,则字符串s可被字符串t整除。 如果s是可整除的,请找到最小的字符串u,以便可以将其串连几次以获得s和t。 如果不能整除,则将返回值设置为-1。 最后,返回字符串u或-1的长度。
示例1:
s =“ bcdbcdbcdbcd”
t =“ bcdbcd”
如果字符串t被串联两次,则结果为“ bcdbcdbcdbcd”,它等于字符串s。字符串s可被字符串t整除。
自从通过第一个测试以来,寻找可以连接以创建字符串s和t的最小字符串u。
字符串“ bcd”是可以连接在一起以创建字符串s和t的最小字符串。
字符串u的长度为3,这是要返回的整数值。
示例2:
s =“ bcdbcdbcd”
t =“ bcdbcd”
如果将字符串t连接两次,则结果为“ bcdbcdbcdbcd”,它大于字符串s。串联的字符串中有一个额外的“ bcd”。
字符串s不能被字符串t整除,因此返回-1。
我有以下代码,但它很“慢”-长字符串需要一段时间。有什么可以优化的呢?这类问题的“正确”算法是什么?
public static void main(String[] args) {
String s1 = "bcdbcdbcdbcd", t1 = "bcdbcd";
String s2 = "bcdbcdbcd", t2 = "bcdbcd";
String s3 = "lrbb", t3 = "lrbb";
System.out.println(getLength(s1, t1));
System.out.println(getLength(s2, t2));
System.out.println(getLength(s3, t3));
}
private static int getLength(String s, String t) {
if(s.length() % t.length() > 0)
return -1;
StringBuilder sb = new StringBuilder();
for(int i=0;i*t.length() < s.length();i++) {
sb.append(t);
}
if(!sb.toString().equals(s))
return -1;
for(int i=1;i<=t.length();i++) {
sb = new StringBuilder();
String subStr = t.substring(0, i);
while(sb.length() < t.length()) {
sb.append(subStr);
}
if(sb.toString().equals(t))
return i;
}
return -1;
}
答案 0 :(得分:0)
在代码的第二部分中,即使sb
不能被t
整除,即subStr
时,您仍要尝试构建t.length() % i > 0
。 / p>
不知道t
的最大长度是多少,但是如果t
是例如一个61的字符串,即使您只应检查StringBuilder
和append()
,由于您正在创建61个i = 1
对象并调用i = 61
322次(自61是素数)。
即使61
检查也是多余的,因为您知道t
本身可以被整除。
进行以下更改:
将i<=t.length()
更改为i<t.length()
在循环内添加以下内容:
if (t.length() % i > 0)
continue;
将最后一个return -1;
更改为return t.length();
在Java 11+中,我们在repeat()
上有了了不起的新String
方法,它比使用StringBuilder
快得多,因此使用Java 11可以将代码缩短为:
private static int getLength(String s, String t) {
if (s.length() % t.length() != 0 || ! s.equals(t.repeat(s.length() / t.length())))
return -1;
for (int i = 1; i < t.length(); i++)
if (t.length() % i == 0 && t.equals(t.substring(0, i).repeat(t.length() / i)))
return i;
return t.length();
}
答案 1 :(得分:0)
第二个for循环只需要检查t.length()的因数,这将使它大大加快。
答案 2 :(得分:0)
KMP 算法是一种可以用 O(n) 有效求解的算法。 This 示例将帮助您在 O(n) 中解决此问题。
第一部分即
"求字符串 s 是否能被字符串 t 整除"
很简单,您可以通过在 StringBuilder(sb) 中附加 t 直到
某人的长度
对于第二部分,即 “如果 s 是可整除的,找到最小的字符串 u,这样它可以连接若干次以获得 s 和 t”。 KMP 算法的“后缀和前缀的最长子串”技术将有助于以优化的方式解决这个问题。