Given two sorted 0-indexed integer arrays nums1 and nums2 as well as an integer k, return thekth(1-based) smallest product ofnums1[i] * nums2[j]where0 <= i < nums1.lengthand0 <= j < nums2.length.
Instead of generating all possible products, we can use binary search to guess the answer. For a guessed product x, we can efficiently count how many pairs have product ≤ x using the sorted property of the arrays. This allows us to find the k-th smallest product without explicitly storing all products.
classSolution {
public:longlong count(const vector<int>& a, const vector<int>& b, longlong x) {
int n = a.size(), m = b.size();
longlong cnt =0;
for (int i =0; i < n; ++i) {
if (a[i] ==0) {
if (x >=0) cnt += m;
} elseif (a[i] >0) {
int l =0, r = m;
while (l < r) {
int mid = (l + r) /2;
if ((longlong)a[i] * b[mid] <= x) l = mid +1;
else r = mid;
}
cnt += l;
} else {
int l =0, r = m;
while (l < r) {
int mid = (l + r) /2;
if ((longlong)a[i] * b[mid] <= x) r = mid;
else l = mid +1;
}
cnt += m - l;
}
}
return cnt;
}
longlongkthSmallestProduct(vector<int>& a, vector<int>& b, longlong k) {
longlong l =-1e10, r =1e10, ans =0;
while (l <= r) {
longlong mid = l + (r - l) /2;
if (count(a, b, mid) < k) l = mid +1;
else ans = mid, r = mid -1;
}
return ans;
}
};
classSolution {
privatelongcount(int[] a, int[] b, long x) {
int m = b.length;
long cnt = 0;
for (int v : a) {
if (v == 0) {
if (x >= 0) cnt += m;
} elseif (v > 0) {
int l = 0, r = m;
while (l < r) {
int mid = (l + r) / 2;
if ((long)v * b[mid]<= x) l = mid + 1;
else r = mid;
}
cnt += l;
} else {
int l = 0, r = m;
while (l < r) {
int mid = (l + r) / 2;
if ((long)v * b[mid]<= x) r = mid;
else l = mid + 1;
}
cnt += m - l;
}
}
return cnt;
}
publiclongkthSmallestProduct(int[] a, int[] b, long k) {
long l =-10000000000L, r = 10000000000L, ans = 0;
while (l <= r) {
long mid = l + (r - l) / 2;
if (count(a, b, mid) < k) l = mid + 1;
else {
ans = mid;
r = mid - 1;
}
}
return ans;
}
}
classSolution {
privatefuncount(a: IntArray, b: IntArray, x: Long): Long {
var cnt = 0Lval m = b.size
for (v in a) {
if (v ==0) {
if (x >=0) cnt += m
} elseif (v > 0) {
var l = 0var r = m
while (l < r) {
val mid = (l + r) / 2if (v.toLong() * b[mid] <= x) l = mid + 1else r = mid
}
cnt += l
} else {
var l = 0var r = m
while (l < r) {
val mid = (l + r) / 2if (v.toLong() * b[mid] <= x) r = mid
else l = mid + 1 }
cnt += m - l
}
}
return cnt
}
funkthSmallestProduct(a: IntArray, b: IntArray, k: Long): Long {
var l = -10000000000Lvar r = 10000000000Lvar ans = 0Lwhile (l <= r) {
val mid = l + (r - l) / 2if (count(a, b, mid) < k) l = mid + 1else {
ans = mid
r = mid - 1 }
}
return ans
}
}
classSolution:
defcount(self, a: list[int], b: list[int], x: int) -> int:
m = len(b)
cnt =0for v in a:
if v ==0:
if x >=0:
cnt += m
elif v >0:
l, r =0, m
while l < r:
mid = (l + r) //2if v * b[mid] <= x:
l = mid +1else:
r = mid
cnt += l
else:
l, r =0, m
while l < r:
mid = (l + r) //2if v * b[mid] <= x:
r = mid
else:
l = mid +1 cnt += m - l
return cnt
defkthSmallestProduct(self, a: list[int], b: list[int], k: int) -> int:
l, r =-10**10, 10**10 ans =0while l <= r:
mid = (l + r) //2if self.count(a, b, mid) < k:
l = mid +1else:
ans = mid
r = mid -1return ans
impl Solution {
pubfnkth_smallest_product(a: Vec<i32>, b: Vec<i32>, k: i64) -> i64 {
fncount(a: &Vec<i32>, b: &Vec<i32>, x: i64) -> i64 {
let m = b.len();
letmut cnt =0i64;
for&v in a {
if v ==0 {
if x >=0 {
cnt += m asi64;
}
} elseif v >0 {
let (mut l, mut r) = (0, m);
while l < r {
let mid = (l + r) /2;
if (v asi64) * (b[mid] asi64) <= x {
l = mid +1;
} else {
r = mid;
}
}
cnt += l asi64;
} else {
let (mut l, mut r) = (0, m);
while l < r {
let mid = (l + r) /2;
if (v asi64) * (b[mid] asi64) <= x {
r = mid;
} else {
l = mid +1;
}
}
cnt += (m - l) asi64;
}
}
cnt
}
let (mut l, mut r) = (-1e10asi64, 1e10asi64);
letmut ans =0i64;
while l <= r {
let mid = l + (r - l) /2;
if count(&a, &b, mid) < k {
l = mid +1;
} else {
ans = mid;
r = mid -1;
}
}
ans
}
}