Minimize sum of absolute differences of same-indexed elements of two given arrays by at most one replacement
Given two arrays A[] and B[] of size N each, the task is to find the minimum possible sum of absolute difference of same indexed elements of the two arrays, i.e. sum of |A[i] – B[i]| for all i such that 0 ≤ i < N by replacing at most one element in A[] with another element of A[].
Examples:
Input: A[] = {6, 4, 1, 9, 7, 5}, B[] = {3, 9, 7, 4, 2, 1}, N = 6
Output: 22
Explanation: Replace A[2] with A[4]. The array A[] modifies to [6, 4, 7, 9, 7, 5]. This yields an absolute sum difference of |6 – 3| + |4 – 9| + |7 – 7| + |9 – 4| + |7 – 2| + |5 – 1| = 22, which is maximum possible.Input: A[] = {2, 5, 8}, B[] = {7, 6, 1}, N = 3
Output: 7
Approach: The idea to solve the problem is to calculate for each B[i] (0 ≤ i < N), the closest element in A[] to B[i] using Binary Search and pick out the best choice.
Follow the steps below to solve the problem.
- Initialize two arrays diff[] and BestDiff[] of size N.
- Initialize a variable sum to 0.
- Traverse from 0 to N – 1 and for each i store diff[i]= abs(A[i] – B[i]) and add diff[i] to sum.
- Sort the array A[] in ascending order.
- Iterate over the indices 0 to N – 1 and for each i, using binary search, find the element in A[] that is closest to B[i], say X and store it in BestDiff[] as BestDiff[i] = abs(B[i] – X)
- Initialize a variable BestPick.
- Iterate over the indices 0 to N – 1 and update BestPick as BestPick = max(BestPick, diff[i]-BestDiff[i])
- Now, Sum – BestPick gives the answer.
Below is an implementation of the above approach:
C++
// C++ program for the above approach #include <bits/stdc++.h> using namespace std; // Function to return minimum sum of absolute // difference of same-indexed elements of two arrays int minAbsoluteSumDiff(vector< int > A, vector< int > B, int N) { // Stores initial sum int sum = 0; // Stores the differences between // same-indexed elements of A[] and B[] int diff[N]; for ( int i = 0; i < N; i++) { // Update absolute difference diff[i] = abs (A[i] - B[i]); // Update sum of differences sum += diff[i]; } // Sort array A[] in ascending order sort(A.begin(), A.end()); // Stores best possible // difference for each i int bestDiff[N]; for ( int i = 0; i < N; i++) { // Find the index in A[] // which >= B[i]. int j = lower_bound(A.begin(), A.end(), B[i]) - A.begin(); // Store minimum of abs(A[j] - B[i]) // and abs(A[j - 1] - B[i]) if (j != 0 && j != N) bestDiff[i] = min( abs (A[j] - B[i]), abs (A[j - 1] - B[i])); // If A[j] can be replaced else if (j == 0) bestDiff[i] = abs (A[j] - B[i]); // If A[j - 1] can be replaced else if (j == N) bestDiff[i] = abs (A[j - 1] - B[i]); } // Find best possible replacement int bestPick = 0; for ( int i = 0; i < N; i++) { bestPick = max(bestPick, diff[i] - bestDiff[i]); } // Return the result return sum - bestPick; } // Driver code int main() { // Input vector< int > A = { 2, 5, 8 }; vector< int > B = { 7, 6, 1 }; int N = 3; cout << minAbsoluteSumDiff(A, B, N) << endl; return 0; } |
Java
// Java program for the above approach import java.io.*; import java.util.*; class GFG { // Recursive implementation of // lower_bound static int lower_bound( int arr[], int low, int high, int X) { // Base Case if (low > high) { return low; } // Find the middle index int mid = low + (high - low) / 2 ; // If arr[mid] is greater than // or equal to X then search // in left subarray if (arr[mid] >= X) { return lower_bound(arr, low, mid - 1 , X); } // If arr[mid] is less than X // then search in right subarray return lower_bound(arr, mid + 1 , high, X); } // Function to return minimum sum of absolute // difference of same-indexed elements of two arrays static int minAbsoluteSumDiff( int A[], int B[], int N) { // Stores initial sum int sum = 0 ; // Stores the differences between // same-indexed elements of A[] and B[] int diff[] = new int [N]; for ( int i = 0 ; i < N; i++) { // Update absolute difference diff[i] = Math.abs(A[i] - B[i]); // Update sum of differences sum += diff[i]; } // Sort array A[] in ascending order Arrays.sort(A); // Stores best possible // difference for each i int bestDiff[] = new int [N]; for ( int i = 0 ; i < N; i++) { // Find the index in A[] // which >= B[i]. int j = lower_bound(A, 0 , N - 1 , B[i]); // Store minimum of abs(A[j] - B[i]) // and abs(A[j - 1] - B[i]) if (j != 0 && j != N) bestDiff[i] = Math.min(Math.abs(A[j] - B[i]), Math.abs(A[j - 1 ] - B[i])); // If A[j] can be replaced else if (j == 0 ) bestDiff[i] = Math.abs(A[j] - B[i]); // If A[j - 1] can be replaced else if (j == N) bestDiff[i] = Math.abs(A[j - 1 ] - B[i]); } // Find best possible replacement int bestPick = 0 ; for ( int i = 0 ; i < N; i++) { bestPick = Math.max(bestPick, diff[i] - bestDiff[i]); } // Return the result return sum - bestPick; } // Driver code public static void main(String[] args) { // Input int A[] = { 2 , 5 , 8 }; int B[] = { 7 , 6 , 1 }; int N = 3 ; System.out.println(minAbsoluteSumDiff(A, B, N)); } } // This code is contributed by Dharanendra L V. |
Python3
# Python3 program for the above approach from bisect import bisect_left,bisect_right # Function to return minimum sum of absolute # difference of same-indexed elements of two arrays def minAbsoluteSumDiff(A, B, N): # Stores initial sum sum = 0 # Stores the differences between # same-indexed elements of A[] and B[] diff = [ 0 ] * N for i in range (N): # Update absolute difference diff[i] = abs (A[i] - B[i]) # Update sum of differences sum + = diff[i] # Sort array A[] in ascending order A.sort() # Stores best possible # difference for each i bestDiff = [ 0 ] * N for i in range (N): # Find the index in A[] # which >= B[i]. j = bisect_left(A, B[i]) # Store minimum of abs(A[j] - B[i]) # and abs(A[j - 1] - B[i]) if (j ! = 0 and j ! = N): bestDiff[i] = min ( abs (A[j] - B[i]), abs (A[j - 1 ] - B[i])) # If A[j] can be replaced elif (j = = 0 ): bestDiff[i] = abs (A[j] - B[i]) # If A[j - 1] can be replaced elif (j = = N): bestDiff[i] = abs (A[j - 1 ] - B[i]) # Find best possible replacement bestPick = 0 for i in range (N): bestPick = max (bestPick, diff[i] - bestDiff[i]) # Return the result return sum - bestPick # Driver code if __name__ = = "__main__" : # Input A = [ 2 , 5 , 8 ] B = [ 7 , 6 , 1 ] N = 3 print (minAbsoluteSumDiff(A, B, N)) # This code is contributed by ukasp |
C#
// C# program for the above approach using System; class GFG { // Recursive implementation of // lower_bound static int lower_bound( int []arr, int low, int high, int X) { // Base Case if (low > high) { return low; } // Find the middle index int mid = low + (high - low) / 2; // If arr[mid] is greater than // or equal to X then search // in left subarray if (arr[mid] >= X) { return lower_bound(arr, low, mid - 1, X); } // If arr[mid] is less than X // then search in right subarray return lower_bound(arr, mid + 1, high, X); } // Function to return minimum sum of absolute // difference of same-indexed elements of two arrays static int minAbsoluteSumDiff( int []A, int []B, int N) { // Stores initial sum int sum = 0; // Stores the differences between // same-indexed elements of A[] and B[] int []diff = new int [N]; for ( int i = 0; i < N; i++) { // Update absolute difference diff[i] = Math.Abs(A[i] - B[i]); // Update sum of differences sum += diff[i]; } // Sort array A[] in ascending order Array.Sort(A); // Stores best possible // difference for each i int []bestDiff = new int [N]; for ( int i = 0; i < N; i++) { // Find the index in A[] // which >= B[i]. int j = lower_bound(A, 0, N - 1, B[i]); // Store minimum of abs(A[j] - B[i]) // and abs(A[j - 1] - B[i]) if (j != 0 && j != N) bestDiff[i] = Math.Min(Math.Abs(A[j] - B[i]), Math.Abs(A[j - 1] - B[i])); // If A[j] can be replaced else if (j == 0) bestDiff[i] = Math.Abs(A[j] - B[i]); // If A[j - 1] can be replaced else if (j == N) bestDiff[i] = Math.Abs(A[j - 1] - B[i]); } // Find best possible replacement int bestPick = 0; for ( int i = 0; i < N; i++) { bestPick = Math.Max(bestPick, diff[i] - bestDiff[i]); } // Return the result return sum - bestPick; } // Driver code public static void Main() { // Input int []A = { 2, 5, 8 }; int []B = { 7, 6, 1 }; int N = 3; Console.Write(minAbsoluteSumDiff(A, B, N)); } } // This code is contributed by ipg2016107. |
Javascript
<script> // JavaScript program for the above approach function lower_bound(arr, low, high, X) { // Base Case if (low > high) { return low; } // Find the middle index var mid = low + (high - low) / 2; // If arr[mid] is greater than // or equal to X then search // in left subarray if (arr[mid] >= X) { return lower_bound(arr, low, mid - 1, X); } // If arr[mid] is less than X // then search in right subarray return lower_bound(arr, mid + 1, high, X); } // Function to return minimum sum of absolute // difference of same-indexed elements of two arrays function minAbsoluteSumDiff(A, B, N) { // Stores initial sum var sum = 0; // Stores the differences between // same-indexed elements of A[] and B[] var diff = new Array(N); for (i = 0; i < N; i++) { // Update absolute difference diff[i] = Math.abs(A[i] - B[i]); // Update sum of differences sum += diff[i]; } // Sort array A[] in ascending order A.sort(); // Stores best possible // difference for each i var bestDiff = new Array(N); var i; for (i = 0; i < N; i++) { // Find the index in A[] // which >= B[i]. var j = lower_bound(A, 0, N - 1, B[i]); // Store minimum of abs(A[j] - B[i]) // and abs(A[j - 1] - B[i]) if (j != 0 && j != N) bestDiff[i] = Math.min(Math.abs(A[j] - B[i]), Math.abs(A[j - 1] - B[i])); // If A[j] can be replaced else if (j == 0) bestDiff[i] = Math.abs(A[j] - B[i]); // If A[j - 1] can be replaced else if (j == N) bestDiff[i] = Math.abs(A[j - 1] - B[i]); } // Find best possible replacement var bestPick = 0; for (i = 0; i < N; i++) { bestPick = Math.max(bestPick, diff[i] - bestDiff[i]); } // Return the result return sum - bestPick; } // Driver code // Input var A = [2, 5, 8]; var B = [7, 6, 1]; var N = 3; document.write(minAbsoluteSumDiff(A, B, N)); </script> |
7
Time Complexity: O(NLogN)
Auxiliary Space:O(N)
Please Login to comment...