Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/139.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ O(logn)算法在预排序列表的并集中查找秩为i的元素_C++_Algorithm - Fatal编程技术网

C++ O(logn)算法在预排序列表的并集中查找秩为i的元素

C++ O(logn)算法在预排序列表的并集中查找秩为i的元素,c++,algorithm,C++,Algorithm,给定两个排序列表,每个列表包含n个实数,是否有O(log n) 假设两个列表的元素不同,计算两个列表并集中秩i元素(其中i以递增顺序响应索引)的时间算法 编辑: @本:这就是我一直在做的,但我还是不明白 我有一个例子 清单A:1,3,5,7 清单B:2,4,6,8 求秩(i)=4 第一步:i/2=2; 列表A现在包含的是A:1、3 列表B现在包含的是B:2,4 compare A[i] to B[i] i.e A[i] is less;

给定两个排序列表,每个列表包含n个实数,是否有O(log n) 假设两个列表的元素不同,计算两个列表并集中秩i元素(其中i以递增顺序响应索引)的时间算法

编辑: @本:这就是我一直在做的,但我还是不明白

我有一个例子

清单A:1,3,5,7 清单B:2,4,6,8

求秩(i)=4

第一步:i/2=2; 列表A现在包含的是A:1、3 列表B现在包含的是B:2,4

         compare A[i] to B[i] i.e 

                 A[i] is less;

                 So the lists now become :

                   A: 3 
                   B: 2,4
第二步: i/2=1

         List A now contains A:3
         List B now contains B:2 

         NoW I HAVE LOST THE VALUE 4 which is actually the result ...

我知道我遗漏了一些东西,但即使经过近一天的思考,我也不能只找出这一个…

当合并两个列表时,您将不得不接触两个列表中的每个元素。如果你不去触摸每一个元素,一些元素就会落在后面。因此,你的理论下界是O(n)。所以你不能那样做

您不必排序,因为您有两个已经排序的列表,您可以在合并过程中保持排序

编辑:哎呀,我误解了这个问题。我认为给定值,你要找到等级,而不是相反的方法。如果您想查找给定的秩值,那么在
O(logn)
中就是这样做的:

是的,如果列表允许
O(1)
随机访问(即它是一个数组而不是一个链表),则可以在
O(log N)
中执行此操作

  • L1上的二进制搜索
  • L2上的二进制搜索
  • 对指数求和
你必须算出数学,+1,-1,如果找不到元素怎么办,等等,但这就是想法。

是:

您知道元素位于第一个列表的索引
[0,i]
或第二个列表的
[0,i]
中。从每个列表中提取元素
i/2
,并进行比较。进行二等分

我没有包含任何代码,因为这个问题听起来很像家庭作业

编辑:二分法是二进制搜索背后的方法。它的工作原理如下:

假设i=10;(基于零的索引,我们正在寻找第11个元素)

在第一步中,您知道答案在列表1(0…10)或列表2(0…10)中。以a=list1(5)和b=list2(5)为例

如果a>b,则列表1中有5个元素位于a之前,列表2中至少有6个元素位于a之前。所以a是结果的上界。同样,列表2中有5个元素位于b之前,而列表1中少于6个元素位于b之前。所以b是结果的下界。现在我们知道结果在列表1(0..5)或列表2(5..10)中。如果a 我们只是重复这个过程,在每一步将搜索空间的大小减少一半。二分法是指我们在已知结果的范围之外选择中间元素(平分线)

所以这个和二进制搜索之间的唯一区别是,在二进制搜索中,我们比较我们要查找的值,但这里我们比较另一个列表中的值

注意:这实际上是
O(logi)
O(logn)
好(至少不差)。此外,对于小i(可能i<100),合并第一个i元素(线性搜索而不是二分法)的操作实际上会更少,因为这要简单得多。当您添加缓存行为和数据局部性时,线性搜索可能会更快,最多可达数千个


此外,如果i>n然后依赖于结果必须在两个列表的末尾这一事实,那么每个列表中的初始候选范围都是从((i-n)…n)

让第一个列表为
ListX
,第二个列表为
ListY
。我们需要找到
ListX[x]
ListY[y]
的正确组合,其中
x+y=i
。由于x,y,i是自然数,我们可以立即将问题域限制为
x*y
。通过使用方程
max(x)=len(ListX)
max(y)=len(ListY)
我们现在有了
x*y
元素的子集,形式为
[x,y]
,我们需要搜索

您将要做的是对这些元素进行排序,如so
[i-max(y),max(y)]
[i-max(y)+1,max(y)-1]
<代码>[max(x),i-max(x)]。然后,通过选择中间的
[x,y]
组合,将此列表平分。由于列表是有序且不同的,因此您可以测试
ListX[x]
。如果为真,则将组合的上半部分对分;如果为假,则将下半部分对分。你会一直平分直到找到正确的组合

我留下了很多细节,但这是主要的要点。它确实是O(log(n))


编辑:正如本所指出的,这实际上是
O(log(i))
。如果我们让
n=len(ListX)+len(ListY)
那么我们知道
i我从问题中收集到,他试图在索引i处找到值,所以他首先得到了一个索引,而不是一个要搜索的值,你可以将其向后搜索(问题是找到给定索引的值,而不是找到给定值的索引),但是使用二进制搜索是正确的。@Ben,@Phil:你说得对,我看错了。我仍然保留我的答案以供学习。您不必完成合并,因此它是
O(I)
而不是
O(n)
。但是你可以完全避免合并。+1!当然,列表必须允许
O(1)
随机访问,但是是的,二进制搜索是关键。嘿,你能告诉我如何进行二分法吗。我是新来的,我在网上读到的大部分材料都与找到复杂的num的根有关