【问题标题】:Is it O(NlogN) or O(N^2)?是 O(NlogN) 还是 O(N^2)?
【发布时间】:2021-10-22 03:38:13
【问题描述】:

我正在尝试解决 BinarySearch.com 上的问题:

给定一个按升序排序的整数列表 nums 和一个整数 k,返回列表中任意两个元素加起来是否为 k。您不能两次使用相同的元素。注意:数字可以是负数或 0。这应该在O(1) 空格中完成。
所以对于nums = [1, 3, 5, 8]k = 6,答案应该是true

我知道可以使用两个指针来完成,但是我正在学习二进制搜索,所以我想出了以下逻辑:

bool solve(vector<int>& nums, int k) {
    for(int i=0; i<nums.size(); i++) {
        auto loc=lower_bound(begin(nums), end(nums), k-nums[i]);
        if(loc!=nums.end()) {
            if(distance(nums.begin(), loc)!=i && *loc+nums[i]==k) return true;
        }
    }
    return false;
}

它被接受了,但是时间复杂度是多少?我不确定它是否是O(NlogN),因为我对nums 中的每个值运行二进制搜索(O(logN) 算法),或者它是否应该是O(N^2),因为当if 条件为真时,我使用distance(),据我了解,它本身就是一个 O(n) 操作。

【问题讨论】:

  • @Someone:对于 std::vector,std::distance 是一个常数时间操作。
  • @AndyG,很酷,谢谢!
  • 改进:*loc+nums[i]==k 总是正确的,因为您刚刚通过搜索找到了*loc == k - nums[i]。您也不需要搜索整个向量;从begin(nums) + i + 1 开始。这也将使您的其他条件变得不必要。
  • @YvesDaoust,抱歉打错了。我的意思是:“我运行二进制搜索(一个 O(logN) 算法)N 次)。
  • @molbdnilo:改进这个版本没有什么意义,因为你可以在没有任何二分搜索的情况下解决问题。

标签: c++ algorithm time-complexity binary-search


【解决方案1】:

正如 cmets 中所指出的,在最坏的情况下,代码会遍历数组并在每一步中对数组执行二进制搜索。因此该操作的复杂度为 O(Nlog(N))。

我使用 distance(),据我了解,它本身就是一个 O(n) 操作。

实际上在 std::vector::iterator 上使用时它是 O(1),因为它是一个 LegacyRandomAccessIterator (Is std::next for vector O(n) or O(1)?) 并且对于这样的迭代器 std::distance is O(1) 所以它不是参与我们的计算。

【讨论】:

  • 这是有道理的。我放慢了速度意味着它们的复杂性更差,所以我想检查一下。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-02-23
相关资源
最近更新 更多