java - 什么是搜索不断变化的字符的字符串的 BigO 表示法
问题描述
我有下面的函数,可以找到字符串中最长的非重复子字符串。我知道 for 循环是 O(n) 但是通过在调用函数的 tmp 字符串中搜索当前字符将是额外的时间indexOf
。
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
(使用运算符+)都发生在每次迭代中,都需要时间O(|S|)
,其中|S|
是tmp
本次迭代的长度。现在,问题是tmp
有界的长度?
如果您的字母表是有限的(例如,如果它只能包含来自 a、b、...、z 的字符) - 那么长度的tmp
大小是有限的(在 az 示例中为 26,这来自鸽洞原理)。在这种情况下,您可以说indexOf()
创建一个新字符串(通过使用运算符 +)需要O(1)
时间,因为它正在创建一个有界大小的字符串。在这种情况下,算法需要O(n)
时间。
但是,如果字母表是无限制的,您可以输入一个完全没有重复的字符串。在这种情况下,循环的每次迭代都需要O(i)
时间。这给了你。
1 + 2 + ... n = n (n+1)/2
在 中O(n^2)
,算法的复杂度变为O(n^2)
推荐阅读
- oracle - SSIS Oracle 提供程序未显示在工具箱中
- reactjs - React useState() 设置状态设置正确但不记录更新的值
- jenkins - 带有 codecov 的 gradle jenkins 管道
- typescript - 在多个 Typescript 接口中使用相似的派生属性名称或基于接口属性名称创建新接口
- checkbox - Blazor 复选框过滤奇怪的渲染
- asp.net-core - 在 ASP.NET core 2.2 发布的站点上应用 Windows 身份验证,而无需获取 chrome 登录对话框
- powershell - PowerShell - 仅选择值 (true/false) 而不是整个对象本身
- mysql - 创建没有死锁和竞争条件的唯一顺序银行帐号
- python - 如何在熊猫数据框中用多个替换一列值
- git - Git合并解决冲突可读性