由两个数组中任意两个元素的乘积形成的数组中第 K 个最小的数
给定两个分别由N和M个整数组成的已排序数组A[]和B[] ,任务是在由数组A[]和B[]中所有可能对的乘积形成的数组中找到第K个最小的数.
例子:
Input: A[] = {1, 2, 3}, B[] = {-1, 1}, K = 4
Output: 1
Explanation: The array formed by the product of any two numbers from array A[] and B[] respectively is prod[] = {-3, -2, -1, 1, 2, 3}. Hence, the 4th smallest integer in the prod[] array is 1.
Input: A[] = {-4, -2, 0, 3}, B[] = {1, 10}, K = 7
Output: 3
方法:给定的问题可以在产品的所有可能值的二进制搜索的帮助下解决。这里讨论的方法与本文讨论的方法非常相似。以下是要遵循的步骤:
- 创建一个函数check(key) ,返回 product 数组中小于 key 的元素个数是否大于K。可以使用类似于本文中讨论的算法的两指针技术来完成。
- 在[INT_MIN, INT_MAX]范围内执行二进制搜索以找到最小的数字ans使得 产品数组中小于ans的元素数量至少为K 。
- 完成上述步骤后,打印ans的值作为结果。
下面是上述方法的实现:
C++
// C++ program for the above approach
#include
using namespace std;
#define int long long
// Function to check if count of elements
// greater than req in product array are
// more than K or not
bool check(int req, vector posA,
vector posB, vector negA,
vector negB, int K)
{
// Stores the count of numbers less
// than or equal to req
int cnt = 0;
// Case with both elements of A[] and
// B[] are negative
int first = 0;
int second = negB.size() - 1;
// Count number of pairs formed from
// array A[] and B[] with both elements
// negative and there product <= req
while (first < negA.size()) {
while (second >= 0
&& negA[first]
* negB[second]
<= req)
second--;
// Update cnt
cnt += negB.size() - second - 1;
first++;
}
// Case with both elements of A[] and
// B[] are positive
first = 0;
second = posB.size() - 1;
// Count number of pairs formed from
// array A[] and B[] with both elements
// positive and there product <= req
while (first < posA.size()) {
while (second >= 0
&& posA[first]
* posB[second]
> req)
second--;
// Update cnt
cnt += second + 1;
first++;
}
// Case with elements of A[] and B[]
// as positive and negative respectively
first = posA.size() - 1;
second = negB.size() - 1;
// Count number of pairs formed from
// +ve integers of A[] and -ve integer
// of array B[] product <= req
while (second >= 0) {
while (first >= 0
&& posA[first]
* negB[second]
<= req)
first--;
// Update cnt
cnt += posA.size() - first - 1;
second--;
}
// Case with elements of A[] and B[]
// as negative and positive respectively
first = negA.size() - 1;
second = posB.size() - 1;
// Count number of pairs formed from
// -ve and +ve integers from A[] and
// B[] with product <= req
for (; first >= 0; first--) {
while (second >= 0
&& negA[first]
* posB[second]
<= req)
second--;
// Update cnt
cnt += posB.size() - second - 1;
}
// Return Answer
return (cnt >= K);
}
// Function to find the Kth smallest
// number in array formed by product of
// any two elements from A[] and B[]
int kthSmallestProduct(vector& A,
vector& B,
int K)
{
vector posA, negA, posB, negB;
// Loop to iterate array A[]
for (const auto& it : A) {
if (it >= 0)
posA.push_back(it);
else
negA.push_back(it);
}
// Loop to iterate array B[]
for (const auto& it : B)
if (it >= 0)
posB.push_back(it);
else
negB.push_back(it);
// Stores the lower and upper bounds
// of the binary search
int l = LLONG_MIN, r = LLONG_MAX;
// Stores the final answer
int ans;
// Find the kth smallest integer
// using binary search
while (l <= r) {
// Stores the mid
int mid = (l + r) / 2;
// If the number of elements
// greater than mid in product
// array are more than K
if (check(mid, posA, posB,
negA, negB, K)) {
ans = mid;
r = mid - 1;
}
else {
l = mid + 1;
}
}
// Return answer
return ans;
}
// Driver Code
int32_t main()
{
vector A = { -4, -2, 0, 3 };
vector B = { 1, 10 };
int K = 7;
cout << kthSmallestProduct(A, B, K);
return 0;
}
Java
// Java program for the above approach
import java.util.*;
class GFG{
// Function to check if count of elements
// greater than req in product array are
// more than K or not
static boolean check(int req, Vector posA,
Vector posB, Vector negA,
Vector negB, int K)
{
// Stores the count of numbers less
// than or equal to req
int cnt = 0;
// Case with both elements of A[] and
// B[] are negative
int first = 0;
int second = negB.size() - 1;
// Count number of pairs formed from
// array A[] and B[] with both elements
// negative and there product <= req
while (first < negA.size()) {
while (second >= 0
&& negA.elementAt(first)
* negB.elementAt(second)
<= req)
second--;
// Update cnt
cnt += negB.size() - second - 1;
first++;
}
// Case with both elements of A[] and
// B[] are positive
first = 0;
second = posB.size() - 1;
// Count number of pairs formed from
// array A[] and B[] with both elements
// positive and there product <= req
while (first < posA.size()) {
while (second >= 0
&& posA.elementAt(first)
* posB.elementAt(second)
> req)
second--;
// Update cnt
cnt += second + 1;
first++;
}
// Case with elements of A[] and B[]
// as positive and negative respectively
first = posA.size() - 1;
second = negB.size() - 1;
// Count number of pairs formed from
// +ve integers of A[] and -ve integer
// of array B[] product <= req
while (second >= 0) {
while (first >= 0
&& posA.elementAt(first)
* negB.elementAt(second)
<= req)
first--;
// Update cnt
cnt += posA.size() - first - 1;
second--;
}
// Case with elements of A[] and B[]
// as negative and positive respectively
first = negA.size() - 1;
second = posB.size() - 1;
// Count number of pairs formed from
// -ve and +ve integers from A[] and
// B[] with product <= req
for (; first >= 0; first--) {
while (second >= 0
&& negA.elementAt(first)
* posB.elementAt(second)
<= req)
second--;
// Update cnt
cnt += posB.size() - second - 1;
}
// Return Answer
return (cnt >= K);
}
// Function to find the Kth smallest
// number in array formed by product of
// any two elements from A[] and B[]
static int kthSmallestProduct(int[] A,
int[] B,
int K)
{
Vector posA = new Vector<>();
Vector negA = new Vector<>();
Vector posB = new Vector<>();
Vector negB = new Vector<>();
// Loop to iterate array A[]
for (int it : A) {
if (it >= 0)
posA.add(it);
else
negA.add(it);
}
// Loop to iterate array B[]
for (int it : B)
if (it >= 0)
posB.add(it);
else
negB.add(it);
// Stores the lower and upper bounds
// of the binary search
int l = Integer.MIN_VALUE, r = Integer.MAX_VALUE;
// Stores the final answer
int ans=0;
// Find the kth smallest integer
// using binary search
while (l <= r) {
// Stores the mid
int mid = (l + r) / 2;
// If the number of elements
// greater than mid in product
// array are more than K
if (check(mid, posA, posB,
negA, negB, K)) {
ans = mid;
r = mid - 1;
}
else {
l = mid + 1;
}
}
// Return answer
return ans;
}
// Driver Code
public static void main(String[] args)
{
int[] A = { -4, -2, 0, 3 };
int[] B = { 1, 10 };
int K = 7;
System.out.print(kthSmallestProduct(A, B, K));
}
}
// This code is contributed by gauravrajput1
Python3
# python program for the above approach
LLONG_MAX = 9223372036854775807
LLONG_MIN = -9223372036854775807
# Function to check if count of elements
# greater than req in product array are
# more than K or not
def check(req, posA, posB, negA, negB, K):
# Stores the count of numbers less
# than or equal to req
cnt = 0
# Case with both elements of A[] and
# B[] are negative
first = 0
second = len(negB) - 1
# Count number of pairs formed from
# array A[] and B[] with both elements
# negative and there product <= req
while (first < len(negA)):
while (second >= 0 and negA[first] * negB[second] <= req):
second -= 1
# Update cnt
cnt += len(negB) - second - 1
first += 1
# Case with both elements of A[] and
# B[] are positive
first = 0
second = len(posB) - 1
# Count number of pairs formed from
# array A[] and B[] with both elements
# positive and there product <= req
while (first < len(posA)):
while (second >= 0 and posA[first] * posB[second] > req):
second -= 1
# Update cnt
cnt += second + 1
first += 1
# Case with elements of A[] and B[]
# as positive and negative respectively
first = len(posA) - 1
second = len(negB) - 1
# Count number of pairs formed from
# +ve integers of A[] and -ve integer
# of array B[] product <= req
while (second >= 0):
while (first >= 0 and posA[first] * negB[second] <= req):
first -= 1
# Update cnt
cnt += len(posA) - first - 1
second -= 1
# Case with elements of A[] and B[]
# as negative and positive respectively
first = len(negA) - 1
second = len(posB) - 1
# Count number of pairs formed from
# -ve and +ve integers from A[] and
# B[] with product <= req
for first in range(first, -1, -1):
while (second >= 0 and negA[first] * posB[second] <= req):
second -= 1
# Update cnt
cnt += len(posB) - second - 1
# Return Answer
return (cnt >= K)
# Function to find the Kth smallest
# number in array formed by product of
# any two elements from A[] and B[]
def kthSmallestProduct(A, B, K):
posA = []
negA = []
posB = []
negB = []
# Loop to iterate array A[]
for it in A:
if (it >= 0):
posA.append(it)
else:
negA.append(it)
# Loop to iterate array B[]
for it in B:
if (it >= 0):
posB.append(it)
else:
negB.append(it)
# Stores the lower and upper bounds
# of the binary search
l = LLONG_MIN
r = LLONG_MAX
# Stores the final answer
ans = 0
# Find the kth smallest integer
# using binary search
while (l <= r):
# Stores the mid
mid = (l + r) // 2
# If the number of elements
# greater than mid in product
# array are more than K
if (check(mid, posA, posB, negA, negB, K)):
ans = mid
r = mid - 1
else:
l = mid + 1
# Return answer
return ans
# Driver Code
if __name__ == "__main__":
A = [-4, -2, 0, 3]
B = [1, 10]
K = 7
print(kthSmallestProduct(A, B, K))
# This code is contributed by rakeshsahni
C#
// C# program for the above approach
using System;
using System.Collections.Generic;
public class GFG {
// Function to check if count of elements
// greater than req in product array are
// more than K or not
static bool check(int req, List posA, List posB, List negA,
List negB, int K) {
// Stores the count of numbers less
// than or equal to req
int cnt = 0;
// Case with both elements of []A and
// []B are negative
int first = 0;
int second = negB.Count - 1;
// Count number of pairs formed from
// array []A and []B with both elements
// negative and there product <= req
while (first < negA.Count) {
while (second >= 0 && negA[first]
* negB[second] <= req)
second--;
// Update cnt
cnt += negB.Count - second - 1;
first++;
}
// Case with both elements of []A and
// []B are positive
first = 0;
second = posB.Count - 1;
// Count number of pairs formed from
// array []A and []B with both elements
// positive and there product <= req
while (first < posA.Count) {
while (second >= 0 && posA[first] * posB[second] > req)
second--;
// Update cnt
cnt += second + 1;
first++;
}
// Case with elements of []A and []B
// as positive and negative respectively
first = posA.Count - 1;
second = negB.Count - 1;
// Count number of pairs formed from
// +ve integers of []A and -ve integer
// of array []B product <= req
while (second >= 0) {
while (first >= 0 && posA[first] * negB[second] <= req)
first--;
// Update cnt
cnt += posA.Count - first - 1;
second--;
}
// Case with elements of []A and []B
// as negative and positive respectively
first = negA.Count - 1;
second = posB.Count - 1;
// Count number of pairs formed from
// -ve and +ve integers from []A and
// []B with product <= req
for (; first >= 0; first--) {
while (second >= 0 && negA[first]* posB[second]<= req)
second--;
// Update cnt
cnt += posB.Count - second - 1;
}
// Return Answer
return (cnt >= K);
}
// Function to find the Kth smallest
// number in array formed by product of
// any two elements from []A and []B
static int kthSmallestProduct(int[] A, int[] B, int K) {
List posA = new List();
List negA = new List();
List posB = new List();
List negB = new List();
// Loop to iterate array []A
foreach (int it in A) {
if (it >= 0)
posA.Add(it);
else
negA.Add(it);
}
// Loop to iterate array []B
foreach (int it in B)
if (it >= 0)
posB.Add(it);
else
negB.Add(it);
// Stores the lower and upper bounds
// of the binary search
int l = int.MinValue, r = int.MaxValue;
// Stores the readonly answer
int ans = 0;
// Find the kth smallest integer
// using binary search
while (l <= r) {
// Stores the mid
int mid = (l + r) / 2;
// If the number of elements
// greater than mid in product
// array are more than K
if (check(mid, posA, posB, negA, negB, K)) {
ans = mid;
r = mid - 1;
} else {
l = mid + 1;
}
}
// Return answer
return ans;
}
// Driver Code
public static void Main(String[] args) {
int[] A = { -4, -2, 0, 3 };
int[] B = { 1, 10 };
int K = 7;
Console.Write(kthSmallestProduct(A, B, K));
}
}
// This code is contributed by gauravrajput1
Javascript
输出:
3
时间复杂度: O((N+M)*log 2 64 ) 或 O((N+M)*64)
辅助空间: O(N+M)