【问题标题】:Big-O time complexity of 4sum problem. Brute force approach4sum 问题的大 O 时间复杂度。蛮力方法
【发布时间】:2021-05-28 06:18:32
【问题描述】:

我正在做这个名为 4sum 的问题。 Link to problem.

给定一个包含 n 个数字和一个整数的数组(这是目标 元素)。计算四边形的总数(收集4 从这 n 个数字中选择的不同数字)在那里 四边形元素的总和将与目标元素相加。

我为蛮力方法编写了这段代码。根据我的说法,大 O 时间复杂度是 --- n^4 log (n^4)。我在下面给出了原因。虽然复杂度应该只有 n^4。请帮助我了解我缺少什么。

set<vector<int>>s;
for (int i = 0; i < n; i++) {
    for (int j = i + 1; j < n; j++) {
        for (int k = j + 1; k < n; k++) {
            for(int l = k + 1; l < n; l++) {
                if (a[i]+a[j]+a[k]+a[l]==target) {
                    s.insert({a[i], a[j], a[k], a[l]});
                }
            }
        }
    }
}

逻辑是生成所有可能的四边形(具有不同元素),然后为每个四边形检查四边形元素的总和是否等于目标。如果是,则将四边形插入集合中。

现在,我们无法知道有多少四边形会匹配此条件,因为这完全取决于输入。但是为了获得上限,我们假设我们检查的每个四边形都满足条件。因此,集合中总共有 N^4 个插入。 对于 N^4 次插入 --- 复杂度为 N^4 log(N^4)。

【问题讨论】:

  • 您是在要求一种具有较低复杂度的新算法,还是您错误地计算了该算法的复杂度?
  • 我在问为什么复杂性是错误的。我在计算复杂性时犯了什么错误。谢谢你的时间。
  • 是什么让你认为你的复杂性是错误的?
  • 一位专家告诉我它应该是 O(n^4)。他可能是错的。请发表您的意见。
  • 专家假设每个四边形的处理时间为 O(1)。如果您是 A) 打印每个四边形,或者 B) 将四边形添加到向量中,或者 C) 将四边形添加到哈希表中,或者 D) 只是计算四边形,那将是正确的。因为您选择将四边形添加到集合中,所以您增加了运行时间。但是,区别在于您增加了实现的运行时间,而不是算法的复杂性。该算法是选择4个索引来创建一个四边形的方法。一旦你发现它不是算法的一部分,你对四边形所做的事情。

标签: c++ algorithm stl set time-complexity


【解决方案1】:
  if (a[i]+a[j]+a[k]+a[l]==target) {
    s.insert({a[i], a[j], a[k], a[l]});
  }

这确实会执行O(N^4) 次。

为了获得上限,我们假设我们检查的每个四边形都满足条件。

正确。

对于 N^4 次插入 --- 复杂度为 N^4 log(N^4)。

不是这样,因为N^4 插入不一定会导致包含N^4 元素的集合。

插入成本为O(log(s.size())。但是s.size()K 不同方式数量的上限,其中target 可以表示为给定范围内4 个整数的总和,因此最坏情况下的成本是O(log(K))。虽然K 可以是一个很大的数字,但它确实依赖于N,因此就N 的复杂性而言,这算作常数时间O(1),因此整体复杂度还是O(N^4)·O(1) = O(N^4)


[ EDIT ] 关于@MysteriousUser 建议使用std::unordered_set 而不是std::set,这确实会将循环体的O(1) 常量更改为更好的常量,但不会更改整体复杂度,仍然是O(N^4)

另一个实际上将复杂性增加到 OP 提出的O(N^4 log(N)) 的选项是std::multi_set,因为在这种情况下,每次插入都会导致多集的大小增加.

【讨论】:

    猜你喜欢
    • 2019-08-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-05-30
    • 1970-01-01
    相关资源
    最近更新 更多