|
| 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 <= i < nums1.length</code><em> and </em><code>0 <= j < nums2.length</code>. |
| 6 | +<p> </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> </p> |
| 43 | +<p><strong>Constraints:</strong></p> |
| 44 | + |
| 45 | +<ul> |
| 46 | + <li><code>1 <= nums1.length, nums2.length <= 5 * 10<sup>4</sup></code></li> |
| 47 | + <li><code>-10<sup>5</sup> <= nums1[i], nums2[j] <= 10<sup>5</sup></code></li> |
| 48 | + <li><code>1 <= k <= 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> </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> </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 | +``` |
0 commit comments