寻找第k最小元素的有序阵列联盟阵列、最小、元素、联盟

2023-09-11 01:56:53 作者:爆炒小月亮

我正在研究在发现两种排序数组的工会第k最小的元素在的莱特code 。我不认为该算法是正确的。有这样一行:我们做的观察,当艾< BJ,那么它必须是真实的爱< BJ-1。另一方面,如果BJ&其中;爱,那么BJ<爱1。。任何怎样才可以真正的我Ĵ

其次,这条线也令我感到困惑:我们试图通过比较A和B的中间分子,这是我们确定为艾和Bj处理这个棘手的问题。如果爱是BJ和Bj-1之间,我们刚刚发现的I + J + 1的最小元素,虽然它出来是真实的。任何人都可以解释的原因是什么?我真的想了解的算法中,我已经通过合并阵列做到了,但那要花费 O(N)的时间,相比 O(日志N)在这里的时间。

解决方案   

我们做的观察,当爱< BJ ,那么它必须是真实的,爱< BJ-1 。在另一方面,如果 BJ< AI ,然后 BJ< AI-1 ..怎么可以适用于任何Ĵ

这是不是适用于所有对Ĵ的。文章认为,一个特殊情况。

首先,假设没有重复,甚至在 A B 。第二,这样的结论

 爱< BJ ==>艾< BJ-1,RESP。 BJ<艾==> BJ<爱1
 

这是没有的

的条件下,由

  BJ-1<艾< BJ RESP。爱1< BJ<嗳
 
DXP元件引脚最小安全间距在哪设置

成立。因此,通过排除这些配置,爱< BJ ==>艾< = BJ-1 BJ<艾==> BJ< =爱1 跟随紧接,然后严格不等式不存在重复的假设遵循

  

我们试图通过比较A和B的中间分子,这是我们确定为艾和Bj处理这个棘手的问题。如果爱是BJ和Bj-1之间,我们刚刚发现的I + J + 1的最小元素

在阵列 B ,还有Ĵ元素比 BJ较小,并在阵列 A ,还有比爱(编号从0开始)。因此,如果 BJ-1<艾< BJ ,这两个数组相加正好包含 J + I ,比更小的元素。

什么变化,如果有重复?

不多。

我们仍然认为其中 I + J = K-1 的情况。让我们假设爱< = BJ

如果艾= BJ ? 如果爱< BJ

在1的情况下,让 M 是最小的指数,这样 AM =爱 N 最小的指数,这样 BN = BJ 。然后,在两个数组在一起,恰好有 M + N< = I + J = K-1 元素严格小于艾小,且至少(I + 1)+(J + 1)=(K + 1)元素不超过爱。因此,第k个最小的元素等于

有关二,我们有三种情况需要考虑,一个) BJ-1< AI ,B) BJ-1 =爱,C) BJ-1> AI

在a)情况下,我们有Ĵ B元素是不大于,而且都是严格的小,我们有 M< = I A 是严格小于艾小( M $)和一个未知的数字,但至少 I-M + 1 元素等于。因此,有完全 J + M< = J + I = K-1 在两个数组一起是严格小于艾较小的元素,且至少 J + M +(I-M + 1)= J + I + 1 = K 元素不超过 AI ,两个数组在一起的,因此第k个最小的元素等于

在情况b),同样的逻辑表明,两个数组在一起的第k个最小的元素等于

在剩余的情况下,爱< BJ-1 ,事情就变得很难更为复杂。阵列 B 至少包含Ĵ元素不大于 BJ-1 和阵列 A 至少包含 I + 1 元素严格小于 Bj- 1 ,因此这两个数组的第k个最小的元素一起至多一样大, BJ-1 。但它不能比艾小 B 至多包含 J-1 元素更小,所以两个数组一起至多包含 1 +(J-1)= K-2 艾元素较小)。

因此​​,我们仍然可以丢弃低于艾部分从数组 A 及以上 BJ-1 从数组 B ,并继续执行,而不重复。

所有这一切变化是,一些严格的不平等必须更换较弱的不平等。

在code(是,如果起始索引和长度获得通过,而不是切片更有效,但切片产量较短code):

 高清kthsmallest(A,B,K):
    如果K< 1:
        返回None
    a_len,b_len = LEN(A),LEN(B)
    如果a_len == 0:
        返回b [K-1]#我们如果B是太短死了,我不在乎
    如果b_len == 0:
        返回A [K-1]#见上
    #拉手边缘情况:如果k == a_len + b_len,我们会
    #走​​出界外的指标,因为I + J< = a_len + b_len  -  2
    #为有效索引i和j
    如果a_len + b_len == K:
        如果A [-1]其中,乙[-1]:
            返回b [-1]
        其他:
            返回A [-1]
    #查找的索引i和j大致正比于的len(A)/ len个(B)的
    I =(a_len *(K-1))//(a_len + b_len)
    J = K-1-i的
    #确保指标是有效的,在不幸的情况下,
    #Ĵ可以设置由上面b_len
    如果J> = b_len:
        J = b_len-1
        I = K-1-j的
    如果A [1]  - ,= B [J]:
        在j == 0或B [J-1] = A [1]:
            返回A [1]
        #A [1]  - ;乙[J-1] =乙[j]的
        返回kthsmallest(A [1:],B [:J],K-I)
    ·B [J] LT; A [1],对称于A [1]  - ; B〔J]。
    如果我== 0或[I-1]; = B [J]:
        返回b [J]。
    ·B [J] LT; A [I-1]
    返回kthsmallest(A [我],B [J:],K-J)
 

I was studying the article on finding the kth-smallest element in the union of two sorted arrays at leetcode. I don't think that the algorithm is correct. There is this line: We make an observation that when Ai < Bj, then it must be true that Ai < Bj-1. On the other hand, if Bj < Ai, then Bj < Ai-1.. How can it be true for any i and j?

And secondly, this line also baffles me: We try to approach this tricky problem by comparing middle elements of A and B, which we identify as Ai and Bj. If Ai is between Bj and Bj-1, we have just found the i+j+1 smallest element, although it comes out to be true. Can anyone explain the reason? I really want to understand the algo, I have done it by merging the arrays, but that takes O(N) time, compared to O(log N) time here.

解决方案

We make an observation that when Ai < Bj, then it must be true that Ai < Bj-1. On the other hand, if Bj < Ai, then Bj < Ai-1.. How can it be true for any i and j?

It isn't true for all pairs of i and j. The article considers a special situation.

First, it is assumed that there are no duplicates, not even in the form of common elements of A and B. Second, the conclusion that

Ai < Bj ==> Ai < Bj-1,   resp.  Bj < Ai ==> Bj < Ai-1

is made under the condition that neither of

Bj-1 < Ai < Bj  resp. Ai-1 < Bj < Ai

holds. So by excluding these configurations, Ai < Bj ==> Ai <= Bj-1 and Bj < Ai ==> Bj <= Ai-1 follow immediately, and the strict inequalities then follow by the assumption that no duplicates exist.

We try to approach this tricky problem by comparing middle elements of A and B, which we identify as Ai and Bj. If Ai is between Bj and Bj-1, we have just found the i+j+1 smallest element

In array B, there are j elements smaller than Bj, and in array A, there are i elements smaller than Ai (indices start at 0). So if Bj-1 < Ai < Bj, both arrays together contain exactly j + i elements that are smaller than Ai.

What changes if there are duplicates?

Not much.

We still consider the situation where i + j = k-1. Let us assume that Ai <= Bj.

What if Ai = Bj? What if Ai < Bj?

In case 1., let m be the smallest index such that Am = Ai, and n the smallest index such that Bn = Bj. Then in both arrays together, there are exactly m + n <= i + j = k-1 elements strictly smaller than Ai, and at least (i+1) + (j+1) = (k+1) elements not larger than Ai. Hence the k-th smallest element is equal to Ai.

For 2., we have three cases to consider, a) Bj-1 < Ai, b) Bj-1 = Ai, c) Bj-1 > Ai.

In case a), we have j elements in B that are not larger than Ai, and they are all strictly smaller, and we have m <= i elements in A that are strictly smaller than Ai (m as above) and an unkown number, but at least i-m+1 elements equal to Ai. So there are exactly j + m <= j + i = k-1 elements in both arrays together that are strictly smaller than Ai, and at least j + m + (i-m+1) = j+i+1 = k elements not larger than Ai, hence the k-th smallest element of both arrays together is equal to Ai.

In case b), the same reasoning shows that the k-th smallest element of both arrays together is equal to Ai.

In the remaining case, Ai < Bj-1, things become hardly more complicated. Array B contains at least j elements not larger than Bj-1, and array A contains at least i+1 elements strictly smaller than Bj-1, hence the k-th smallest element of both arrays together is at most as large as Bj-1. But it cannot be smaller than Ai (B contains at most j-1 elements smaller than Ai, so both arrays together contain at most i + (j-1) = k-2 elements smaller than Ai).

So we can still discard the part below Ai from the array A and the part above Bj-1 from the array B and proceed as without duplicates.

All that changed was that a few strict inequalities had to be replaced with weak inequalities.

The code (would be more efficient if starting indices and lengths were passed instead of slicing, but slicing yields shorter code):

def kthsmallest(A, B, k):
    if k < 1:
        return None
    a_len, b_len = len(A), len(B)
    if a_len == 0:
        return B[k-1] # let it die if B is too short, I don't care
    if b_len == 0:
        return A[k-1] # see above
    # Handle edge case: if k == a_len + b_len, we would
    # get an out-of-bounds index, since i + j <= a_len+b_len - 2
    # for valid indices i and j
    if a_len + b_len == k:
        if A[-1] < B[-1]:
            return B[-1]
        else:
            return A[-1]
    # Find indices i and j approximately proportional to len(A)/len(B)
    i = (a_len*(k-1)) // (a_len+b_len)
    j = k-1-i
    # Make sure the indices are valid, in unfortunate cases,
    # j could be set to b_len by the above
    if j >= b_len:
        j = b_len-1
        i = k-1-j
    if A[i] <= B[j]:
        if j == 0 or B[j-1] <= A[i]:
            return A[i]
        # A[i] < B[j-1] <= B[j]
        return kthsmallest(A[i:], B[:j], k-i)
    # B[j] < A[i], symmetrical to A[i] < B[j]
    if i == 0 or A[i-1] <= B[j]:
        return B[j]
    # B[j] < A[i-1]
    return kthsmallest(A[:i], B[j:], k-j)