介绍
存在两个非降序排列的整数数组 $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)$