从两个数组中找到总和小于最接近它的目标的 ID 对
给定两个数组arr1[]和arr2[] ,大小分别为N和M ,形式为{ID, value}和一个整数目标,任务是从两个数组中找到所有ID对,使得对的值是最大值,并且最多具有M值。
例子:
Input: arr1[] = [[1, 2000], [2, 3000], [3, 2000]], arr2[] = [[1, 2500], [2, 3000], [3, 3000]], target = 6000
Output:
2 2
2 3
Explanation:
Following are the pairs of elements from the two arrays arr1[] and arr2[]:
- (arr1[2], arr2[2]): The sum of elements 3000 + 3000 = 6000(= target) and closest to the value target. Print the IDs as (2, 2).
- (arr1[2], arr2[3]): The sum of elements 3000 + 3000 = 6000(= target) and closest to the value target. Print the IDs as (2, 3).
Input: arr1[] = [[1, 2000], [2, 3000], [3, 2000]], arr2[] = [[1, 3000], [2, 3000]], target = 5500
Output:
1 1
1 2
3 1
3 2
方法:给定的问题可以使用 TreeMap 数据结构来存储数组元素arr1[]并有效地找到另一个数组arr2[]中每个元素的对。以下是步骤:
- 创建一个 TreeMap,其中键是数组元素的值,值是ID列表。
- 迭代数组arr1[]并将其元素插入 TreeMap。
- 初始化一个变量,比如最接近目标以跟踪最接近目标的值并且不超过它。
- 初始化 ArrayList结果以存储所有可能的 ID 对。
- 迭代数组arr2[]并为每个元素计算要在 TreeMap 中搜索的剩余值。
- 如果剩余的值,比如(target – arr2[i])小于0 ,则无法形成对,因此继续迭代。
- 使用 TreeMap 的 floorKey()函数查找小于或等于剩余值的值。如果上述函数的返回值为null ,则找不到对应的元素。
- 如果返回值,比如currentTarget大于closeTarget ,则更新最接近目标并将 arrayList result[]重新初始化为一个新列表。
- 遍历键为currentTarget的 id 列表,并将所有可能的 ID 对组合添加到结果列表中。
- 完成上述步骤后,打印存储在 ArrayList result[]中的所有 ID 对。
下面是上述方法的实现:
Java
// Java program for the above approach
import java.io.*;
import java.util.*;
class GFG {
// Function to find pairs of ids with
// sum of values closest to the target
// but not exceeding the target
public static void closestPair(
int[][] arr1, int[][] arr2, int target)
{
// Initialize TreeMap having array
// element value as key and list of
// ids as value in the TreeMap
TreeMap > valueToIds
= new TreeMap<>();
// list to store all answer pairs
List result = new ArrayList<>();
// Keeps the track of maximum sum
// of pair values not exceeding target
int closestTarget = 0;
// Iterate through the array arr1 and
// add all elements in the TreeMap
for (int[] a : arr1) {
int val = a[1], id = a[0];
valueToIds.putIfAbsent(
val, new ArrayList<>());
valueToIds.get(val).add(id);
}
for (int[] b : arr2) {
// Find the corresponding value
// to be found
int remaining = target - b[1];
if (remaining < 0)
continue;
// Find a value which is close to
// desired value, not exceeding it
Integer floor = valueToIds.floorKey(
remaining);
// No value found which is less
// than or equal to floor
if (floor == null)
continue;
int currentTarget = b[1] + floor;
if (currentTarget >= closestTarget) {
if (currentTarget > closestTarget) {
// Update closeTarget and reset
// result list
closestTarget = currentTarget;
result = new ArrayList<>();
}
// Add all possible pairs in
// result list
for (int id : valueToIds.get(floor))
result.add(
new int[] { id, b[0] });
}
}
// Print all the id pairs
for (int[] ans : result) {
System.out.println(
ans[0] + " " + ans[1]);
}
}
// Driver Code
public static void main(String[] args)
{
int[][] arr1
= { { 1, 2000 }, { 2, 3000 }, { 3, 2000 } };
int[][] arr2 = { { 1, 3000 },
{ 2, 3000 } };
int target = 5500;
closestPair(arr1, arr2, target);
}
}
输出:
1 1
3 1
1 2
3 2
时间复杂度: O(N*log N + M)
辅助空间: O(N*M)