下面的Java代码产生有效的输出,但是执行起来需要更多时间。代码在eclipse中可以正常工作,但由于需要花费更多的时间执行,因此无法在hackerrank或hackerearth这样的在线编译器中工作。有人帮助我找到了解决时间复杂性问题的方法。
我试图找到解决问题的方法,但是我无法通过减少时间来解决问题。
Scanner scan = new Scanner(System. in );
String s = "aab";
String s1 = "";
String s2 = "";
int n1 = 0;
int length = 0;
long n = 882787;
long count = 0;
while (s1.length() < n) {
s1 = s1 + s;
}
if (s1.length() > n) {
count = s1.length() - n;
n1 = (int) count;
}
for (int i = 0; i < s1.length() - n1; i++) {
if (s1.charAt(i) == 'a') {
length += 1;
}
}
System.out.println(length);
上述程序的说明: 我有一个字符串s,用小写英文字母表示。我已将该字符串重复了n次,并将其存储在新字符串中。 我必须在新字符串中找到'a'的出现次数
我该如何减少上述程序的时间复杂度
预先感谢
答案 0 :(得分:1)
我将使用正则表达式基于仅由字母'a'组成的初始输入来创建String
。取那个String
的长度,然后乘以n
。那一行看起来像
System.out.println(s.replaceAll("[^a]+", "").length() * n);
答案 1 :(得分:1)
您将s
添加到字符串n/s.length()
次,称为N:
int N = n / s.length();
每次向字符串中添加s
时,都要在s
中附加数字As:
int a = 0;
for (int i = 0; i < s.length(); ++i) {
a += s.charAt(i) == 'a' ? 1 : 0;
}
// Or int a = s.replaceAll("[^a]", "").length();
因此将它们加倍:
int length = a * N;
答案 2 :(得分:0)
字符串是不可变的。修改字符串实际上是创建一个新的String对象,并将新旧字符串都放入Java String constant poom
如果您不想更改算法,建议您使用StringBuilder来提高执行速度。请注意,StringBuilder不是线程安全的
String s="aab";
int n1 = 0;
StringBuilder sb1 = new StringBuilder();
int length=0;
long n=882787;
long count=0;
while(sb1.length() < n) {
sb1.append(s);
}
if(sb1.length()>n) {
count =sb1.length()-n;
n1=(int)count;
}
for(int i=0;i<sb1.length()- n1;i++) {
if(sb1.charAt(i)=='a') {
length+=1;
}
}
System.out.println(length);
来自here
何时使用哪一个:
如果字符串在整个程序中保持不变,则 使用String类对象,因为String对象是不可变的。如果一个 字符串可以更改(例如: 字符串的构造),并且只能从单个字符串访问 线程,使用StringBuilder就足够了。如果字符串可以更改, 并将从多个线程访问,请使用StringBuffer,因为 StringBuffer是同步的,因此您具有线程安全性。
答案 3 :(得分:0)
我看到了多种可能的优化方法:
a)一种不好的模式是通过重复的字符串连接来创建许多字符串。每个“ s1 = s1 + s;”创建一个新的String实例,该实例将在命令下次运行时被废弃(这会增加负载,因为String实例将成为垃圾收集器的额外工作)。
b)通常:如果发现算法花费的时间太长,则应该考虑一种解决该问题的全新方法。因此,不同的解决方案可能是: -您知道要具有的长度(n)和用于创建大字符串的小字符串(s1)的长度。这样就可以计算出:小字符串在目标字符串中出现的频率是多少?还剩下几个字符? ==>您只需检查要查找的字符的小字符串。将这个数字乘以小字符串在大字符串内的频率是您获得的第一个结果。 ==>现在,您需要检查缺少的小字符串的子字符串。
示例:n = 10,s1 =“ aab”,寻找“ a”: 因此,首先我们检查s1多长时间插入一次包含n个字符的新字符串n / length(s1)=> 3 因此,我们检查“ a”在“ aab”内部的频率-> 2 第一个结果是3 * 2 = 6 但是到目前为止,我们检查了3 * 3 = 9个字符,但是我们想要10个字符。因此,我们需要检查s1的n%length(s1)= 1个字符,并且在此子字符串(“ a”)中,wie有1个a,因此我们必须加1。 所以结果是7,而我们没有构建一个大字符串(根本不需要!)
答案 4 :(得分:0)
只需用n
检查字符在原始字符中出现了多少次。这是一种甚至不使用正则表达式的简单方法:
// take these as function input or w/e
String s = "aab";
String find = "a";
long n = 882787;
int count = s.length() - s.replaceAll(find, "").length();
System.out.println(count * n);