Skip to content
Related Articles

Related Articles

Improve Article

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

  • Difficulty Level : Medium
  • Last Updated : 07 Jun, 2021

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)

 

Attention reader! Don’t stop learning now. Get hold of all the important DSA concepts with the DSA Self Paced Course at a student-friendly price and become industry ready.  To complete your preparation from learning a language to DS Algo and many more,  please refer Complete Interview Preparation Course.

In case you wish to attend live classes with experts, please refer DSA Live Classes for Working Professionals and Competitive Programming Live for Students.




My Personal Notes arrow_drop_up
Recommended Articles
Page :