202 Kth Smallest In Two Sorted Arrays (Lai)
Given two sorted arrays of integers, find the Kth smallest number.
Assumptions
- The two given arrays are not null and at least one of them is not empty
- K >= 1, K <= total lengths of the two sorted arrays
Examples
- A = {1, 4, 6}, B = {2, 3}, the 3rd smallest number is 3.
- A = {1, 2, 3, 4}, B = {}, the 2nd smallest number is 2.
Solution:
public class Solution {
public int kth(int[] a, int[] b, int k) {
int[] merged = new int[a.length + b.length];
int i = 0, j = 0, idx = 0;
// 合并两个有序数组
while (i < a.length && j < b.length) {
if (a[i] < b[j]) {
merged[idx++] = a[i++];
} else {
merged[idx++] = b[j++];
}
}
// 如果有剩余,直接复制到合并后的数组中
while (i < a.length) {
merged[idx++] = a[i++];
}
while (j < b.length) {
merged[idx++] = b[j++];
}
// 直接访问第 K 个元素
return merged[k - 1];
}
}
// TC: O(n)
// SC: O(n)
public class Solution {
public int kth(int[] a, int[] b, int k) {
// Assumptions: a, b is not null, at least one of them
// is not empty, k <= a.length + b.length, k >= 1
return kth(a, 0, b, 0, k);
}
// in the subarray of a starting from index aleft, and
// subarray of b starting from index bleft, find the kth smallest
// element among these two subarrays.
private int kth(int[] a, int aleft, int[] b, int bleft, int k){
// three base cases:
// 1. we already eliminate all the elements in a.
// 2. we already eliminate all the elements in b.
// 3. when k is reduced to 1, don't miss this base case.
// The reason why we have as base case is in the following
// logic we need k >= 2 to make it work.
if (aleft >= a.length){
return b[bleft + k - 1];
}
if (bleft >= b.length){
return a[aleft + k - 1];
}
if (k == 1){
return Math.min(a[aleft], b[bleft]);
}
// we compare the k/2 the element in a's subarray
// and the k/2 th element in b's subarray.
// to determine which k/2 partition can be surely included
// in the smallest k elements.
int amid = aleft + k / 2 - 1;
int bmid = bleft + k / 2 - 1;
int aval;
int bval;
if (amid >= a.length){
aval = Integer.MAX_VALUE;
}else{
aval = a[amid];
}
if (bmid >= b.length){
bval = Integer.MAX_VALUE;
}else{
bval = b[bmid];
}
if (aval <= bval){
return kth(a, amid + 1, b, bleft, k - k/2);
}else{
return kth(a, aleft, b, bmid + 1, k - k/2);
}
}
}
// TC: O(logk)
// SC: O(logk)