警告:在阅读过该主题的每个人都意识到他们不知道自己在说什么(包括我)之前,添加了此答案的声誉。如果将来某个时候有一个公认的答案与该算法的所有文档不矛盾,请多加注意!
简而言之:
2*(whatever) 位很容易解释,我在下面做了。 (无论如何)位让我非常困惑,据我所知应该是
2*(count1)
并且与第二个范围的长度完全无关。要么我遗漏了某些东西(很可能),要么文档有误(那不是很好......)。
如果您想了解我的推理,请参见下文。如果我错了并且有人有正确的答案,请告诉我,以便我删除此帖子!
为什么是 2 *(count1 等)
如果你问为什么是 2 次 (count1 + count2) -1,关键就在这一行:
第一个版本使用 operator
每次比较两个元素时,都会做两次比较:我不等于它,它不等于我。
这些“比较对”的最大数量很难确定。事实上,我想不通。据我所知,它应该与第二个范围的长度无关......
为什么不是 (count1 + count2 -1) 或 (count1 + count2) -1
我已经看了好几天,并根据cppreference 中的代码示例做了一些测试,老实说,我不知道这是怎么回事。
算法暗示并且 OP 挖出的消息来源说 range2 必须是 range1 的子集,并且两者都是排序的,因此没有必要检查元素两次。这意味着算法必须最多检查 range1 的所有元素,再加上一个额外的检查 range2 的元素是否大于 range1 中的任何元素。不仅如此,无论 range2 中有 2 个或 20 个元素,它仍然进行完全相同数量的比较。
比较有两种可能的定义,显然会给出不同的答案:
comparison == 算法中的所有比较操作
在这种情况下,会发生以下比较:
- 我是否到达了最后一个 range2 元素
- 我是否到达了最后一个 range1 元素
- 是 range2 elem
- 是 range2 elem > range1 elem
在简单的情况下 N1 == N2 == 1,这可以产生至少 6 次比较(例如,1、2、3、4、1、2:其中 range1 = {1} 和 range2 = {10} ),这远远超过任何一种算法所允许的。所以这不可能。
比较 == 检查 elem1 和 elem2 是否相等
在这种情况下,对 range1 的每个元素进行两次比较,直到找到 range2 的所有元素或到达 range1 的末尾并停止(发现它已到达 range1 的末尾)。
因此,据我所知,复杂度与N2的长度无关,复杂度应该是
2*(N1)
请注意,对于“比较”的这个定义,2*(N1 + N2 - 1) 似乎只适用于 N2 == 1,而 2*(N1 + N2) -1 永远不会作为比较次数成立仅在非最大复杂度情况下为奇数(range2 的数字不在 range1 内且不大于 max(range1))。
比较的任何其他定义都是有选择性的。我能想到的唯一另一件事是编译器优化了某些步骤,比如当元素没有增加时不检查它是否再次到达 range2 的末尾(这也会使算法根据需要依赖于 N2 ),但是我看不到任何其他可以优化的东西,以便将数字降低到完全匹配任一陈述的复杂性。
...其他人有更好的答案吗?我现在和 OP 一样好奇。