问题描述
我具有下面的功能,该功能可找到字符串中最长的非重复子字符串。
我知道for循环是O(n),但是通过在函数indexOf
的调用中在tmp字符串中搜索当前char会花费额外的时间。
public static String find(String input) {
String currentLongest = input.length() > 0 ? "" + input.charat(0) : "";
String tmp = currentLongest;
for (int i = 1; i < input.length(); i++) {
int index = tmp.indexOf(""+input.charat(i));
if (index == -1) {
tmp = tmp + input.charat(i);
if (tmp.length() > currentLongest.length())
currentLongest = tmp;
} else
tmp = tmp.substring(index+1)+input.charat(i);
}
return currentLongest;
}
解决方法
indexOf()
和重新创建tmp
(使用operator +)都发生在每次迭代中,都需要O(|S|)
时间,其中|S|
是{{1 }}。现在,问题是tmp
有界吗?
如果您的字母是有限的(例如,如果它只能包含a,b,...,z中的字符)-那么tmp
的长度是有限的(在az示例中为26,它来自pigeonhole principle)。在这种情况下,您可以说tmp
并创建一个新字符串(通过使用运算符+)花费了indexOf()
时间,因为它正在创建一个有界大小的字符串。在这种情况下,该算法将花费 O(1)
时间。
但是,如果字母是无限的,则可以有一个完全没有重复的输入字符串。
在这种情况下,循环的每次迭代都花费O(n)
时间。这给你。
O(i)
在1 + 2 + ... n = n (n+1)/2
中,并且算法的复杂度变为 O(n^2)