【问题标题】:What is the complexity of this algorithm? (java)这个算法的复杂度是多少? (爪哇)
【发布时间】:2019-01-05 21:51:56
【问题描述】:

while 循环是O(logn)O(n) 内部循环是否会工作,因为它将最多连接 n 个字符(总共导致 O(logn + n))?使用 StringBuilder 会变成 O(1) 吗?

List<String> l = new ArrayList<>();
// some code to add N items to l
//.
//.
//.
while (l.size() > 1) {
    int lo = 0, hi = l.size() - 1;
    List<String> temp = new ArrayList<>();
    while (lo < hi) {
        temp.add("(" + l.get(lo) + "," + l.get(hi) + ")");
        lo++;
        hi--;
    }
    l = temp;
}

【问题讨论】:

  • @Strom 什么? O(2) 甚至是什么意思?现在,我可能不是编程方面最有经验的人,但我确实在我的数据结构和算法课程中给予了足够的关注,以了解没有 O(2)、O(3) 或 O(60) 这样的东西就此而言(等等)。 Big-O 用于描述算法的性能或复杂性。这不是一个真正的计时器。
  • @Strom 上面的代码无法计算为 O(1) 或任何其他常量/固定时间。列表的大小决定了这里的大部分运行时间,导致外循环和内循环都是 O(N)。由于这里的字符串连接本身是 O(N),所以我们得到 O(NNN) = O(N^3)。

标签: java string time-complexity big-o complexity-theory


【解决方案1】:

我提出了多种解决方案,输出字符串的最佳解决方案是修改您的原始帖子。

此解决方案将匹配使用 StringBuilder(l.size * 2 -1) 的算法时间。 * 2 - 1 允许使用逗号。

下面的解决方案将内部循环减少到 O(1),通过预先分配具有最大元素数的数组列表,每个元素都可以直接分配。您的原始代码需要对 arraylist 的所有元素进行深拷贝,导致添加新元素的时间为 O(N),超出了 arraylist 的初始容量。以下代码将数组列表初始化为适当的大小。

整个复杂度是1/2 * N + (1/2 * (N - 1) + (1/4 * (N - 2)) + (1/8 * (N -3))... )

我的数学/分析可能不正确,但是,给出的下限是数组中所有元素的字符串连接至少需要 N 次操作 => O(N) 假设我的数学在上面是正确的,上限也是 O(N)。因为任何小于一半的值都不能加到一个值上,使总和高于原始值。

如果我的数学错了,最坏的情况是 N log N。

绝对上限是 N 的平方(如果你忽略 N 每次迭代都会减少的事实)。

List<String> l = new ArrayList<>();
// some code to add N items to l
//.
//.
//.
while (l.size() > 1) {
    int lo = 0, hi = l.size() - 1;
    List<String> temp = new ArrayList<>(l.size/2 + 1);
    while (lo < hi) {
        temp.add("(" + l.get(lo) + "," + l.get(hi) + ")");
        lo++;
        hi--;
    }
    l = temp;
}

在实践中,1/2 N ArrayLists 的内存分配和取消分配对于除中小 N 值之外的所有值,成为算法的限制因素。

【讨论】:

    猜你喜欢
    • 2023-03-07
    • 1970-01-01
    • 2015-06-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多