Open In App

Minimize sum of absolute differences of same-indexed elements of two given arrays by at most one replacement

Improve
Improve
Like Article
Like
Save
Share
Report

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.

  1. Initialize two arrays diff[] and BestDiff[] of size N.
  2. Initialize a variable sum to 0.
  3. Traverse from 0 to N – 1 and for each i store diff[i]= abs(A[i] – B[i]) and add diff[i] to sum.
  4. Sort the array A[] in ascending order.
  5. 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)
  6. Initialize a variable BestPick.
  7. Iterate over the indices 0 to N – 1 and update BestPick as BestPick = max(BestPick, diff[i]-BestDiff[i])
  8. 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>


Output: 

7

 

Time Complexity: O(NLogN)
Auxiliary Space:O(N)

 



Last Updated : 07 Jun, 2021
Like Article
Save Article
Previous
Next
Share your thoughts in the comments
Similar Reads