给定数组对的绝对差的最小可能和
给定大小分别为 N 和 M (N < M)的两个数组a[]和b[] ,任务是找到通过将数组a[]的每个元素与一个元素配对形成的对的绝对差的最小可能和数组b[]
注意:每个数组的每个元素只能被考虑一次。
例子:
Input: a[] = {2, 3, 5}, b[] = {1, 2, 3, 4, 5}
Output: 0
Explanation: Elements {2, 3, 5} in array a[] can be paired with {2, 3, 5} in array b[].
This will give a minimum absolute difference of 0.
Input: a[] = {1, 4, 5, 8}, b[] = {1, 3, 4, 6, 7}
Output: 2
天真的方法:最简单的方法是对数组进行排序并尝试所有可能的组合以从b[]中选择N个元素并与a[]配对。
时间复杂度: O(N*logN + M*logM + M C N )
辅助空间: O(1)
Efficient Approach:这个问题可以通过使用动态规划的概念使用以下思想来有效地解决。
For each element at ith position of array a[], the jth element of b[] can either be used to form a pair with a[i] or not.
So the overlapping subproblem property can be used to form a dp[][] array to store the minimum absolute difference till ith element of b[] and jth element of a[] is considered and can be reused for further calculations.
按照下面提到的步骤来实现上述想法:
- 首先对两个数组进行排序。
- 初始化一个矩阵dp[][]其中dp[i][j]表示总的最小绝对差,直到 b[] 的第 i 个索引和 a [ ]的第 j 个索引为止。
- 在遍历较大数组b[]的索引时,在每个迭代点可能有两种情况:
- 不考虑第 i 个索引,以形成具有最小绝对差和的对。然后dp[i+1][j] = dp[i][j]不考虑第 i个索引,直接移动到第 (i+1) 个索引。
- 考虑第 i 个索引。因此,将第 i 个和第 j 个索引处的元素之间的绝对差相加,然后分别移动到第 (i+1) 个和第(j+1) 个索引。所以总值是dp[i+1][j+1] = dp[i][j] + abs(a[j] – b[i]) 。
- dp[M][N]处的值是必需的答案。
下面是上述方法的实现。
C++
// C++ code to implement above approach
#include
using namespace std;
// Function to return the
// minimum absolute difference
int min_sum(int a[], int b[], int N, int M)
{
// Sorting both the arrays
sort(a, a + N);
sort(b, b + M);
int dp[M + 1][N + 1];
// Initialising the dp to high value
for (int i = 0; i <= M; i++) {
for (int j = 0; j <= N; j++) {
dp[i][j] = 1e9;
}
}
dp[0][0] = 0;
// Iterating through each element
// of the larger array b
for (int i = 0; i < M; i++) {
// Case 1. Where we are not taking
// the element at ith index
for (int j = 0; j <= N; j++) {
dp[i + 1][j] = dp[i][j];
}
// Case 2. When we have to take the
// element at ith index
for (int j = 0; j < N; j++) {
dp[i + 1][j + 1]
= min(dp[i + 1][j + 1],
dp[i][j]
+ abs(a[j] - b[i]));
}
}
return dp[M][N];
}
// Driver code
int main()
{
int a[] = { 1, 4, 5, 8 };
int N = sizeof(a) / sizeof(a[0]);
int b[] = { 1, 3, 4, 6, 7 };
int M = sizeof(b) / sizeof(b[0]);
// Function call
cout << min_sum(a, b, N, M);
return 0;
}
Java
// Java program to implement above approach
import java.util.*;
class GFG {
// Function to return the
// minimum absolute difference
static int min_sum(int[] a, int[] b, int N, int M)
{
// Sorting both the arrays
Arrays.sort(a);
Arrays.sort(b);
int[][] dp = new int[M + 1][N + 1];
// Initialising the dp to high value
for (int i = 0; i <= M; i++) {
for (int j = 0; j <= N; j++) {
dp[i][j] = 1000000000;
}
}
dp[0][0] = 0;
// Iterating through each element
// of the larger array b
for (int i = 0; i < M; i++) {
// Case 1. Where we are not taking
// the element at ith index
for (int j = 0; j <= N; j++) {
dp[i + 1][j] = dp[i][j];
}
// Case 2. When we have to take the
// element at ith index
for (int j = 0; j < N; j++) {
dp[i + 1][ j + 1]
= Math.min(dp[i + 1][j + 1],
dp[i][j]
+ Math.abs(a[j] - b[i]));
}
}
return dp[M][N];
}
// Driver Code
public static void main(String args[])
{
int[] a = { 1, 4, 5, 8 };
int N = a.length;
int[] b = { 1, 3, 4, 6, 7 };
int M = b.length;
// Function call
System.out.print(min_sum(a, b, N, M));
}
}
// This code is contributed by code_hunt.
Python3
# python3 code to implement above approach
# Function to return the
# minimum absolute difference
def min_sum(a, b, N, M):
# Sorting both the arrays
a.sort()
b.sort()
dp = [[0 for _ in range(N+1)] for _ in range(M+1)]
# Initialising the dp to high value
for i in range(0, M + 1):
for j in range(0, N+1):
dp[i][j] = int(1e9)
dp[0][0] = 0
# Iterating through each element
# of the larger array b
for i in range(0, M):
# Case 1. Where we are not taking
# the element at ith index
for j in range(0, N+1):
dp[i + 1][j] = dp[i][j]
# Case 2. When we have to take the
# element at ith index
for j in range(0, N):
dp[i + 1][j + 1] = min(dp[i + 1][j + 1],
dp[i][j]
+ abs(a[j] - b[i]))
return dp[M][N]
# Driver code
if __name__ == "__main__":
a = [1, 4, 5, 8]
N = len(a)
b = [1, 3, 4, 6, 7]
M = len(b)
# Function call
print(min_sum(a, b, N, M))
# This code is contributed by rakeshsahni
C#
// C# code to implement above approach
using System;
public class GFG{
// Function to return the
// minimum absolute difference
static int min_sum(int[] a, int[] b, int N, int M)
{
// Sorting both the arrays
Array.Sort(a);
Array.Sort(b);
int[,] dp = new int[M + 1, N + 1];
// Initialising the dp to high value
for (int i = 0; i <= M; i++) {
for (int j = 0; j <= N; j++) {
dp[i,j] = 1000000000;
}
}
dp[0,0] = 0;
// Iterating through each element
// of the larger array b
for (int i = 0; i < M; i++) {
// Case 1. Where we are not taking
// the element at ith index
for (int j = 0; j <= N; j++) {
dp[i + 1, j] = dp[i, j];
}
// Case 2. When we have to take the
// element at ith index
for (int j = 0; j < N; j++) {
dp[i + 1, j + 1]
= Math.Min(dp[i + 1, j + 1],
dp[i, j]
+ Math.Abs(a[j] - b[i]));
}
}
return dp[M, N];
}
// Driver code
static public void Main (){
int[] a = { 1, 4, 5, 8 };
int N = a.Length;
int[] b = { 1, 3, 4, 6, 7 };
int M = b.Length;
// Function call
Console.Write(min_sum(a, b, N, M));
}
}
// This code is contributed by hrithikgarg03188.
Javascript
2
时间复杂度: O(N*logN + M*logM + N * M)
辅助空间: O(N * M)