performance - 这是正确的时间复杂度吗?
问题描述
我这样做是为了解决其中一个 leetcode 问题,但我不确定我的算法的复杂性是什么。
public String countAndSay(int n) {
if (n == 1) return "1";
String pre = countAndSay(n-1);
char[] prev = pre.toCharArray();
int len = prev.length;
if (len == 1 && prev[0] == '1') return "11";
int idx = 1;
int rep = 1;
String res = "";
while (idx <= len) {
if (idx == len) {
res += (Integer.toString(rep) + prev[idx-1]);
break;
}
if (prev[idx-1] == prev[idx]) rep++;
else {
res += (Integer.toString(rep) + prev[idx-1]);
rep = 1;
}
idx++;
}
return res;
}
由于递归发生了 n 次并且循环是 O(n),我觉得它应该是 O(n^2)。那是对的吗?如果不是,你能解释一下为什么吗?
解决方案
以下是一些事实:
- 该方法在 input 上递归调用自身
n-1
。 - 该方法产生的序列称为look-and-say 序列。
- 结果字符串的长度随着基数 λ 呈指数增长,其中 λ = 1.303577269034... 是康威常数,因此长度为
O(λ^n)
。 - 循环是字符串长度的二次方(因为重复的字符串连接),所以我们有
O((λ^n)^2) = O((λ^2)^n)
for 循环。
因此,我们可以推导出以下递归关系:
T(0) = 1
T(n) = T(n-1) + O((λ^2)^n)
该关系的渐近行为由下式给出
T(n) ∈ Θ((λ^2)^n) = Θ(1.6993^n)
如果您使用 aStringBuilder
而不是进行邪恶的重复字符串连接,则可以将其归结为Θ(λ^n)
对于此问题也将是渐近最优的。
推荐阅读
- android - 如何在没有重复的 recyclerview 中显示 Firebase 数据
- python - 模块“keras.backend”没有属性“tf”
- php - SMTP 错误:无法连接到服务器:无法建立连接,因为目标机器主动拒绝它
- python - Python:初始化二维数组的不同方法给出不同的输出
- php - PHP 读取 .txt 文件并创建一个数组
- python - 具有多个 n 数的时间序列数据预测
- angular - ion-img 在旧版本的 ionic ~3.* 上无法正常工作
- java - 从 Spring Boot 自定义验证器返回不同的 HTTP 状态代码
- python - 在 Python 中使用版本号对元组列表进行排序
- python - 如何遍历数据框中的列并在每次迭代中打印每个值