给你两个 从小到大排好序 且下标从 0 开始的整数数组 nums1 和 nums2 以及一个整数 k ,请你返回第 k (从 1 开始编号)小的 nums1[i] * nums2[j] 的乘积,其中 0 <= i < nums1.length 且 0 <= j < nums2.length 。
示例 1:
输入:nums1 = [2,5], nums2 = [3,4], k = 2
输出:8
解释:第 2 小的乘积计算如下:
- nums1[0] * nums2[0] = 2 * 3 = 6
- nums1[0] * nums2[1] = 2 * 4 = 8
第 2 小的乘积为 8 。
示例 2:
输入:nums1 = [-4,-2,0,3], nums2 = [2,4], k = 6
输出:0
解释:第 6 小的乘积计算如下:
- nums1[0] * nums2[1] = (-4) * 4 = -16
- nums1[0] * nums2[0] = (-4) * 2 = -8
- nums1[1] * nums2[1] = (-2) * 4 = -8
- nums1[1] * nums2[0] = (-2) * 2 = -4
- nums1[2] * nums2[0] = 0 * 2 = 0
- nums1[2] * nums2[1] = 0 * 4 = 0
第 6 小的乘积为 0 。
示例 3:
输入:nums1 = [-2,-1,0,1,2], nums2 = [-3,-1,2,4,5], k = 3
输出:-6
解释:第 3 小的乘积计算如下:
- nums1[0] * nums2[4] = (-2) * 5 = -10
- nums1[0] * nums2[3] = (-2) * 4 = -8
- nums1[4] * nums2[0] = 2 * (-3) = -6
第 3 小的乘积为 -6 。
提示:
1 <= nums1.length, nums2.length <= 5 * 104
-105 <= nums1[i], nums2[j] <= 105
1 <= k <= nums1.length * nums2.length
nums1 和 nums2 都是从小到大排好序的。
来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/kth-smallest-product-of-two-sorted-arrays
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
第一想法:将num1数组最小值分别与num2数组的数相乘,将这些值存入sub数组,然后对sub数组来一次冒泡排序(就是最简单的暴力破解。。)
long long kthSmallestProduct(int* nums1, int nums1Size, int* nums2, int nums2Size, long long k){//数据集一大起来就TLE了。。
int a=nums2Size*nums1Size;
long long sub[a];
int m=0;
for(int i=0;i<nums1Size;i++){
for(int j=0;j<nums2Size;j++){
sub[m]= (long long)nums1[i] * nums2[j];
m++;
}
}
for(int n=0;n<a-1;n++){
for(int p=0;p<a-n-1;p++){
if(sub[p]>sub[p+1]){
long long swap;
swap=sub[p+1];
sub[p+1]=sub[p];
sub[p]=swap;
}
}
}
return (long long) sub[k-1];
}
不出意外。。
然后只能考虑一种循环少点的写法了。。比如分类讨论
long long kthSmallestProduct(vector<int>& nums1, vector<int>& nums2, long long k) {
vector<int> neg1, pos1, neg2, pos2;
for(int v : nums1) (v < 0)? neg1.push_back(v) : pos1.push_back(v);
for(int v : nums2) (v < 0)? neg2.push_back(v) : pos2.push_back(v);
long long l = -1e10, r = 1e10;
while(l < r) {
long long m = (l + r) >> 1;//>>是右移一次,相当于/2,后面的参数是移位次数,m初始0
long long cur = 0;
for(int i = 0, j = (int)pos2.size() - 1; i < pos1.size(); ++i) {
while(j >= 0 && 1ll * pos1[i] * pos2[j] > m) --j;//ill是将这个数转化为long long类型的参数
cur += j + 1;//找到满足k的
}
for(int i = 0, j = 0; i < neg1.size(); ++i) {
while(j < pos2.size() && 1ll * neg1[i] * pos2[j] > m) ++j;
cur += (int)pos2.size() - j;
}
for(int i = 0, j = 0; i < pos1.size(); ++i) {
while(j < neg2.size() && 1ll * pos1[i] * neg2[j] <= m) ++j;
cur += j;
}
for(int i = 0, j = (int)neg2.size() - 1; i < neg1.size(); ++i) {
while(j >= 0 && 1ll * neg1[i] * neg2[j] <= m) --j;
cur += (int)neg2.size() - 1 - j;
}
if(cur < k) l = m + 1;
else r = m;
}
return l;
}