Skip to content

Commit d607678

Browse files
committed
feat: add solution 2040. Kth Smallest Product of Two Sorted Arrays
1 parent b6b4a67 commit d607678

File tree

2 files changed

+187
-0
lines changed

2 files changed

+187
-0
lines changed
Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
# [2040. Kth Smallest Product of Two Sorted Arrays](https://leetcode.com/problems/kth-smallest-product-of-two-sorted-arrays)
2+
3+
## Description
4+
5+
<div class="elfjS" data-track-load="description_content">Given two <strong>sorted 0-indexed</strong> integer arrays <code>nums1</code> and <code>nums2</code> as well as an integer <code>k</code>, return <em>the </em><code>k<sup>th</sup></code><em> (<strong>1-based</strong>) smallest product of </em><code>nums1[i] * nums2[j]</code><em> where </em><code>0 &lt;= i &lt; nums1.length</code><em> and </em><code>0 &lt;= j &lt; nums2.length</code>.
6+
<p>&nbsp;</p>
7+
<p><strong class="example">Example 1:</strong></p>
8+
9+
<pre><strong>Input:</strong> nums1 = [2,5], nums2 = [3,4], k = 2
10+
<strong>Output:</strong> 8
11+
<strong>Explanation:</strong> The 2 smallest products are:
12+
- nums1[0] * nums2[0] = 2 * 3 = 6
13+
- nums1[0] * nums2[1] = 2 * 4 = 8
14+
The 2<sup>nd</sup> smallest product is 8.
15+
</pre>
16+
17+
<p><strong class="example">Example 2:</strong></p>
18+
19+
<pre><strong>Input:</strong> nums1 = [-4,-2,0,3], nums2 = [2,4], k = 6
20+
<strong>Output:</strong> 0
21+
<strong>Explanation:</strong> The 6 smallest products are:
22+
- nums1[0] * nums2[1] = (-4) * 4 = -16
23+
- nums1[0] * nums2[0] = (-4) * 2 = -8
24+
- nums1[1] * nums2[1] = (-2) * 4 = -8
25+
- nums1[1] * nums2[0] = (-2) * 2 = -4
26+
- nums1[2] * nums2[0] = 0 * 2 = 0
27+
- nums1[2] * nums2[1] = 0 * 4 = 0
28+
The 6<sup>th</sup> smallest product is 0.
29+
</pre>
30+
31+
<p><strong class="example">Example 3:</strong></p>
32+
33+
<pre><strong>Input:</strong> nums1 = [-2,-1,0,1,2], nums2 = [-3,-1,2,4,5], k = 3
34+
<strong>Output:</strong> -6
35+
<strong>Explanation:</strong> The 3 smallest products are:
36+
- nums1[0] * nums2[4] = (-2) * 5 = -10
37+
- nums1[0] * nums2[3] = (-2) * 4 = -8
38+
- nums1[4] * nums2[0] = 2 * (-3) = -6
39+
The 3<sup>rd</sup> smallest product is -6.
40+
</pre>
41+
42+
<p>&nbsp;</p>
43+
<p><strong>Constraints:</strong></p>
44+
45+
<ul>
46+
<li><code>1 &lt;= nums1.length, nums2.length &lt;= 5 * 10<sup>4</sup></code></li>
47+
<li><code>-10<sup>5</sup> &lt;= nums1[i], nums2[j] &lt;= 10<sup>5</sup></code></li>
48+
<li><code>1 &lt;= k &lt;= nums1.length * nums2.length</code></li>
49+
<li><code>nums1</code> and <code>nums2</code> are sorted.</li>
50+
</ul>
51+
</div>
52+
53+
<p>&nbsp;</p>
54+
55+
## Solutions
56+
57+
**Solution: `Binary Search`**
58+
59+
- Time complexity: <em>O((n+m)\*log(maxProduct))</em>
60+
- Space complexity: <em>O(n+m)</em>
61+
62+
<p>&nbsp;</p>
63+
64+
### **JavaScript**
65+
66+
```js
67+
/**
68+
* @param {number[]} nums1
69+
* @param {number[]} nums2
70+
* @param {number} k
71+
* @return {number}
72+
*/
73+
const kthSmallestProduct = function (nums1, nums2, k) {
74+
const negNums1 = [];
75+
const posNums1 = [];
76+
let negNums2 = [];
77+
let posNums2 = [];
78+
79+
for (const num of nums1) {
80+
num < 0 ? negNums1.push(-num) : posNums1.push(num);
81+
}
82+
83+
for (const num of nums2) {
84+
num < 0 ? negNums2.push(-num) : posNums2.push(num);
85+
}
86+
87+
const negCount = negNums1.length * posNums2.length + posNums1.length * negNums2.length;
88+
let sign = 1;
89+
let left = 0;
90+
let right = 10 ** 10;
91+
92+
negNums1.reverse();
93+
negNums2.reverse();
94+
95+
if (k > negCount) {
96+
k -= negCount;
97+
} else {
98+
sign = -1;
99+
k = negCount - k + 1;
100+
[negNums2, posNums2] = [posNums2, negNums2];
101+
}
102+
103+
const getSmallerCount = (a, b, product) => {
104+
let count = 0;
105+
let index = b.length - 1;
106+
107+
for (const num of a) {
108+
while (index >= 0 && num * b[index] > product) {
109+
index -= 1;
110+
}
111+
112+
count += index + 1;
113+
}
114+
115+
return count;
116+
};
117+
118+
while (left < right) {
119+
const mid = Math.floor((left + right) / 2);
120+
const kth = getSmallerCount(negNums1, negNums2, mid) + getSmallerCount(posNums1, posNums2, mid);
121+
122+
kth >= k ? (right = mid) : (left = mid + 1);
123+
}
124+
125+
return left * sign;
126+
};
127+
```
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
/**
2+
* @param {number[]} nums1
3+
* @param {number[]} nums2
4+
* @param {number} k
5+
* @return {number}
6+
*/
7+
const kthSmallestProduct = function (nums1, nums2, k) {
8+
const negNums1 = [];
9+
const posNums1 = [];
10+
let negNums2 = [];
11+
let posNums2 = [];
12+
13+
for (const num of nums1) {
14+
num < 0 ? negNums1.push(-num) : posNums1.push(num);
15+
}
16+
17+
for (const num of nums2) {
18+
num < 0 ? negNums2.push(-num) : posNums2.push(num);
19+
}
20+
21+
const negCount = negNums1.length * posNums2.length + posNums1.length * negNums2.length;
22+
let sign = 1;
23+
let left = 0;
24+
let right = 10 ** 10;
25+
26+
negNums1.reverse();
27+
negNums2.reverse();
28+
29+
if (k > negCount) {
30+
k -= negCount;
31+
} else {
32+
sign = -1;
33+
k = negCount - k + 1;
34+
[negNums2, posNums2] = [posNums2, negNums2];
35+
}
36+
37+
const getSmallerCount = (a, b, product) => {
38+
let count = 0;
39+
let index = b.length - 1;
40+
41+
for (const num of a) {
42+
while (index >= 0 && num * b[index] > product) {
43+
index -= 1;
44+
}
45+
46+
count += index + 1;
47+
}
48+
49+
return count;
50+
};
51+
52+
while (left < right) {
53+
const mid = Math.floor((left + right) / 2);
54+
const kth = getSmallerCount(negNums1, negNums2, mid) + getSmallerCount(posNums1, posNums2, mid);
55+
56+
kth >= k ? (right = mid) : (left = mid + 1);
57+
}
58+
59+
return left * sign;
60+
};

0 commit comments

Comments
 (0)