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.
It isn’t true for all pairs of
iandj. The article considers a special situation.First, it is assumed that there are no duplicates, not even in the form of common elements of
AandB. Second, the conclusion thatis made under the condition that neither of
holds. So by excluding these configurations,
Ai < Bj ==> Ai <= Bj-1andBj < Ai ==> Bj <= Ai-1follow immediately, and the strict inequalities then follow by the assumption that no duplicates exist.In array
B, there arejelements smaller thanBj, and in arrayA, there areielements smaller thanAi(indices start at 0). So ifBj-1 < Ai < Bj, both arrays together contain exactlyj + ielements that are smaller thanAi.What changes if there are duplicates?
Not much.
We still consider the situation where
i + j = k-1. Let us assume thatAi <= Bj.Ai = Bj?Ai < Bj?In case 1., let
mbe the smallest index such thatAm = Ai, andnthe smallest index such thatBn = Bj. Then in both arrays together, there are exactlym + n <= i + j = k-1elements strictly smaller thanAi, and at least(i+1) + (j+1) = (k+1)elements not larger thanAi. Hence the k-th smallest element is equal toAi.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
jelements inBthat are not larger thanAi, and they are all strictly smaller, and we havem <= ielements inAthat are strictly smaller thanAi(mas above) and an unkown number, but at leasti-m+1elements equal toAi. So there are exactlyj + m <= j + i = k-1elements in both arrays together that are strictly smaller thanAi, and at leastj + m + (i-m+1) = j+i+1 = kelements not larger thanAi, hence the k-th smallest element of both arrays together is equal toAi.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. ArrayBcontains at leastjelements not larger thanBj-1, and arrayAcontains at leasti+1elements strictly smaller thanBj-1, hence the k-th smallest element of both arrays together is at most as large asBj-1. But it cannot be smaller thanAi(Bcontains at mostj-1elements smaller thanAi, so both arrays together contain at mosti + (j-1) = k-2elements smaller thanAi).So we can still discard the part below
Aifrom the arrayAand the part aboveBj-1from the arrayBand 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):