从每个 Array 中选择 4 个唯一位置元素的方法计数最多为 K
给定四个数组A[]、B[]、C[]、D[]和一个整数K。任务是找到四个唯一索引p、q、r、s的组合数,使得A[p] + B[q] + C[r] + D[s] ≤ K 。
例子:
Input: A = {2, 3}, B = {5, 2}, C = {0}, D = {1, 2}, K = 6
Output: 3
Explanation: The following are the required combinations:
{2, 2, 0, 1}, {2, 2, 0, 2}, {3, 2, 0, 1}
Input: A = {1, 1}, B = {0}, C = {0}, D = {0}, K = 1
Output: 2
天真的方法:蛮力将使用四个嵌套循环构建四个数字的所有组合的总和,并计算这些总和中最多有多少 K。
时间复杂度: O(N 4 ) 其中 N 是这四个数组中的最大大小
辅助空间: O(1)
高效方法:通过使用分而治之和二分搜索改进上述方法。请按照以下步骤解决问题:
- 为A, B和C, D生成所有可能的配对组合。
- 假设每个数组的长度为 n,那么我们将有两个数组,每个数组的长度为 n*n。让它成为merge1和merge2 。
- 对合并数组之一进行排序,比如说merge2。
- 遍历未排序的merge1数组,找出merge2中有多少元素可以与小于或等于K的总和配对。它可以通过使用二分搜索轻松完成。
下面是上述方法的实现。
C++
// C++ to implement the above approach
#include
using namespace std;
// Function to get the number of combinations
int fourSumLessThanK(vector& A, vector& B,
vector& C, vector& D,
int K)
{
vector merge1;
vector merge2;
int res = 0;
for (int i : A) {
for (int j : B) {
// Merging A and B into merge1
merge1.push_back(i + j);
}
}
for (int i : C) {
for (int j : D) {
// Merging C and D into merge2
merge2.push_back(i + j);
}
}
// Sorting merge2
sort(merge2.begin(), merge2.end());
// Looping through unsorted merge1
for (int i : merge1) {
int l = 0, r = merge2.size() - 1;
int pos = -1;
// Binary search to find how many
// Element from merge2 can be paired
// With merge1 element with sum less
// Than or equal to K
while (l <= r) {
int mid = l + (r - l) / 2;
if (merge2[mid] + i <= K) {
pos = mid;
l = mid + 1;
}
else {
r = mid - 1;
}
}
// Adding the number
// Of pairs in the result
res += pos + 1;
}
return res;
}
// Driver Code
int main()
{
vector A = { 2, 3 };
vector B = { 5, 2 };
vector C = { 0 };
vector D = { 1, 2 };
int K = 6;
// Function call
cout << fourSumLessThanK(A, B, C, D, K);
return 0;
}
Java
// Java code for the above approach
import java.util.*;
class GFG {
// Function to get the number of combinations
static int fourSumLessThanK(int A[], int B[],
int C[], int D[],
int K)
{
List merge1=new ArrayList();
List merge2=new ArrayList();
int res = 0;
for (int i = 0; i < A.length; i++) {
for (int j = 0; j < B.length; j++) {
// Merging A and B into merge1
merge1.add(A[i] + B[j]);
}
}
for (int i = 0; i < C.length; i++) {
for (int j = 0; j < D.length; j++) {
// Merging C and D into merge2
merge2.add(C[i] + D[j]);
}
}
// Sorting merge2
Collections.sort(merge2);
// Looping through unsorted merge1
for (int i = 0; i < merge1.size(); i++) {
int l = 0, r = merge2.size() - 1;
int pos = -1;
// Binary search to find how many
// Element from merge2 can be paired
// With merge1 element with sum less
// Than or equal to K
while (l <= r) {
int mid = l + (r - l) / 2;
if (merge2.get(mid) + merge1.get(i) <= K) {
pos = mid;
l = mid + 1;
}
else {
r = mid - 1;
}
}
// Adding the number
// Of pairs in the result
res += pos + 1;
}
return res;
}
// Driver Code
public static void main (String[] args) {
int A[] = { 2, 3 };
int B[] = { 5, 2 };
int C[] = { 0 };
int D[] = { 1, 2 };
int K = 6;
System.out.println(fourSumLessThanK(A, B, C, D, K));
}
}
// This code is contributed by hrithikgarg03188.
Python3
# Python code for the above approach
# Function to get the number of combinations
def fourSumLessThanK(A, B, C, D, K):
merge1=[];
merge2=[];
res = 0;
for i in range(len(A)):
for j in range(len(B)):
# Merging A and B into merge1
merge1.append(A[i] + B[j]);
for i in range(len(C)):
for j in range(len(D)):
# Merging C and D into merge2
merge2.append(C[i] + D[j]);
# Sorting merge2
merge2.sort()
# Looping through unsorted merge1
for i in range(len(merge1)):
l = 0;
r = len(merge2) - 1;
pos = -1;
# Binary search to find how many
# Element from merge2 can be paired
# With merge1 element with sum less
# Than or equal to K
while (l <= r):
mid = (l +r) // 2;
if (merge2[mid] + merge1[i] <= K):
pos = mid;
l = mid + 1;
else:
r = mid - 1;
# Adding the number
# Of pairs in the result
res = res + pos + 1;
return res;
# Driver Code
A = [ 2, 3 ];
B = [ 5, 2 ];
C = [ 0 ];
D = [ 1, 2 ];
K = 6;
# Function call
print(fourSumLessThanK(A, B, C, D, K));
# This code is contributed by Potta Lokesh
C#
// C# code for the above approach
using System;
using System.Collections;
class GFG {
// Function to get the number of combinations
static int fourSumLessThanK(int []A, int []B,
int []C, int []D,
int K)
{
ArrayList merge1 = new ArrayList();
ArrayList merge2 = new ArrayList();
int res = 0;
for (int i = 0; i < A.Length; i++) {
for (int j = 0; j < B.Length; j++) {
// Merging A and B into merge1
merge1.Add(A[i] + B[j]);
}
}
for (int i = 0; i < C.Length; i++) {
for (int j = 0; j < D.Length; j++) {
// Merging C and D into merge2
merge2.Add(C[i] + D[j]);
}
}
// Sorting merge2
merge2.Sort();
// Looping through unsorted merge1
for (int i = 0; i < merge1.Count; i++) {
int l = 0, r = merge2.Count - 1;
int pos = -1;
// Binary search to find how many
// Element from merge2 can be paired
// With merge1 element with sum less
// Than or equal to K
while (l <= r) {
int mid = l + (r - l) / 2;
if ((int)merge2[mid] + (int)merge1[i] <= K) {
pos = mid;
l = mid + 1;
}
else {
r = mid - 1;
}
}
// Adding the number
// Of pairs in the result
res += pos + 1;
}
return res;
}
// Driver Code
public static void Main () {
int []A = { 2, 3 };
int []B = { 5, 2 };
int []C = { 0 };
int []D = { 1, 2 };
int K = 6;
Console.WriteLine(fourSumLessThanK(A, B, C, D, K));
}
}
// This code is contributed by Samim Hossain Mondal.
Javascript
输出
3
时间复杂度: O(N 2 * logN)
辅助空间: O(N 2 )