Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/elixir/2.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
Algorithm 在2排序数组的并集中寻找第k个最小元素_Algorithm - Fatal编程技术网

Algorithm 在2排序数组的并集中寻找第k个最小元素

Algorithm 在2排序数组的并集中寻找第k个最小元素,algorithm,Algorithm,我想这个问题被问了很多次,但仍然没有明确的答案! 无论如何,这就是我在O(k)中找到的好答案(也可能是O(logm+logn))。但我不明白,如果M_B>M_A(或其他方式),我们应该在M_B之后扔掉元素。但这里是在M_B之前的反向扔掉元素。有人能解释为什么吗 另一个问题是做K/2。。。我们应该这样做,但这对我来说并不明显 [编辑1] Example A = [2, 9, 15, 22, 24, 25, 26, 30] B = [1, 4, 5, 7, 18, 22, 27, 33] k= 6

我想这个问题被问了很多次,但仍然没有明确的答案! 无论如何,这就是我在O(k)中找到的好答案(也可能是O(logm+logn))。但我不明白,如果M_B>M_A(或其他方式),我们应该在M_B之后扔掉元素。但这里是在M_B之前的反向扔掉元素。有人能解释为什么吗

另一个问题是做K/2。。。我们应该这样做,但这对我来说并不明显

[编辑1]

Example
A = [2, 9, 15, 22, 24, 25, 26, 30]
B = [1, 4, 5, 7, 18, 22, 27, 33]
k= 6

Answer is 9 (A[1])
下面是我的想法,如果我想在O(logk)中求解。。。每次需要抛出k/2个元素。 基本解决方案:如果K<2:从-A[0],A[1],B[0],B[1]返回第二小元素 其他: 比较A[k/2]和B[k/2]:如果A[k/2]B[k/2]做类似的事情)。所以现在的问题是下次k指数也是k还是k/2

我所做的是正确的?

该算法并不坏——它比这里通常引用的算法好,所以,在我看来,因为它简单得多——但它有一个巨大的缺陷:它要求两个向量都至少有
k
元素。(问题是它们都有相同数量的元素,
n
,但从未指定
n≥ k
;函数甚至不允许你告诉它向量有多大。但是,这很容易解决。我现在把它作为一个练习。一般来说,我们需要一个这样的算法来处理不同大小的数组,确实如此;我们只需要弄清楚先决条件。)

floor
ceil
的使用既好又具体,但可能会让人困惑。让我们以最一般的方式来看一下。此外,引用的解决方案似乎假设数组是1索引的(即
A[1]
是第一个元素,而不是
A[0]
)。但是,我将要编写的描述使用了更类似C的伪代码,因此它假定
a[0]
是第一个元素。因此,我将编写它以在组合集中查找元素
k
,即
(k+1)第
元素。最后,我要描述的解决方案与给出的解决方案有细微的不同,这在最终条件中会很明显。嗯,它稍微好一点

好的,如果序列中
x
是元素
k
,那么序列中正好有
k
元素小于
x
(我们不会处理重复元素的情况,但是没有太大的不同。参见注3。)

假设我们知道
A
B
都有一个元素
k
(记住,这意味着它们都至少有
k+1
元素)。选择任何小于
k
的非负整数;我们称之为
i
。并让
j
k-i-1
(这样
i+j==k-1
)[参见下面的注释1.]现在,看看元素
A[i]
B[j]
。假设
A[i]
更小,因为我们只需要在另一种情况下更改所有名称。请记住,我们假设所有元素都不同。现在我们知道:

1)
A
中有
i
元素,它们是

2) 在
B
中有
j
元素,它们是

3)
A[i]

4) 从(2)和(3)中,我们知道:

5) 在
B
中,最多有
j
元素是

6) 从(1)和(5)中,我们知道:

7)
A
B
中最多有
i+j
元素,它们是

8) 但是
i+j
k-1
,所以实际上我们知道:

9) 合并数组的元素
k
必须大于
A[i]
(因为
A[i]
最多是元素
i+j

因为我们知道答案必须大于A[i]
,所以我们可以通过[i]放弃[0](实际上,我们只是增加一个数组指针,但实际上我们会放弃它们)。但是,我们现在已经放弃了原始问题中的
i+1
元素。因此,在新的元素集合中(在缩短的
A
和原始的
B
中),我们需要元素
k-(i+1)
,而不是元素
k

现在,让我们检查前提条件。我们说
A
B
都有一个元素
k
元素,所以它们都至少有
k+1
元素。在新问题中,我们想知道缩短的
A
和原始的
B
是否都至少有
k-i
元素。显然
B
确实如此,因为
k-i
不大于
k
。此外,我们还从
A
中删除了
i+1
元素。最初它至少有
k+1
元素,所以现在它至少有
k-i
元素。所以我们在那没问题

最后,让我们检查终止条件。一开始我说我们选择非负整数
I
j
,这样
I+j==k-1
。如果
k==0
,这是不可能的,但是对于
k==1
,这是可以做到的。因此,我们只需要在
k
达到0时执行一些特殊操作,在这种情况下,我们需要执行的是返回
min(A[0],B[0])
。[这是一个比您所看到的算法中更简单的终止条件,请参见注释2。]

那么,挑选
i
的好策略是什么呢?我们最终将从问题中删除
i+1
k-i
元素,我们希望这是尽可能接近一半的元素。所以我们应该选择
i=floor((k-1)/2)
。虽然这可能不是立即发生的