介绍
存在两个非降序排列的整数数组 $A
$ 和 $B
$,数组的长度分别为 $m
$ 和 $n
$,找出它们合并后的数组中的第 $k
$ (从 $1
$ 开始)个数。
|
|
|
|
解决方法
遍历
最基本的方法就是按照 合并两个有序数组 的步骤来寻找第 $k
$ 个数。
|
|
|
|
- 时间复杂度:$
\mathcal{O}(k)
$ - 空间复杂度:$
\mathcal{O}(1)
$
二分搜索
方法一
我们首先来判断第 $k
$ 个数能否在数组 $B
$ 中。
如果 $
B[i]
$ 可以排在第 $k
$ 个数,那么必须 最多($\le
$) 有 $k-1
$ 个数 小于 $B[i]
$,至少 ($\ge
$)有 $k-1
$ 个数 小于等于 $B[i]
$。 即如果 小于 $B[i]
$ 的数的 个数多于($\gt
$)$k-1
$ 个,那么 $B[i]
$ 必然排在第 $k
$ 个数之后。如果 小于等于 $B[i]
$ 的数的 个数少于($\lt
$)$k-1
$ 个,那么 $B[i]
$ 必然排在第 $k
$ 个数之前。
假设 $B[i]
$ 按顺序可以插在 $A
$ 中的 $[a,b]
$ 位置,即 C++ 中 equal_range 表示的范围,如 $3
$ 可以插在数组 $[1,2,2,3,3,3,4,5]
$ 中的下标位置为 $3,4,5,6
$。
即范围 $[a,b]
$ 说明了 $A
$ 中下标范围为 $[0,a-1]
$ 的数都 小于 $B[i]
$,共 $a
$ 个。下标范围为 $[0,b-1]
$ 的数都 小于等于 $B[i]
$,共 $b
$ 个。
而在 $B
$ 中下标范围为 $[0,i-1]
$ 的数都 小于等于 $B[i]
$,共 $i
$ 个。
所以 $B[i]
$ 可以排列的位置为 $[a+i+1,b+i+1]
$。
- 如果 $
k \lt a+i+1
$,说明 $B[i]
$ 排在第 $k
$ 个数之后,第 $k
$ 个数可能在 $[0,i-1]
$ 中。 - 如果 $
k \gt b+i+1
$,说明 $B[i]
$ 排在第 $k
$ 个数之前,第 $k
$ 个数可能在 $[i+1,n-1]
$ 中。 - 否则 $
a+i+1 \le k \le b+i+1
$,$B[i]
$ 一定可以可以排在第 $k
$ 个数位置,直接返回 $B[i]
$ 就可以。
如果上面的步骤找不到 $B[i]
$,则说明 $B
$ 中不存在可以排在第 $k
$ 个位置的数,那第 $k
$ 个数一定在 $A
$ 中,此时直接返回 find_kth(B, A, k)
重新进行搜索就可以。
|
|
|
|
- 时间复杂度:$
\mathcal{O}(\log(m)\log(n))
$ - 空间复杂度:$
\mathcal{O}(1)
$