Skip to content
Related Articles

Related Articles

Minimize remaining array element by removing pairs and replacing them by their absolute difference
  • Last Updated : 11 Feb, 2021

Given an array arr[] consisting of N positive integers, the task is to minimize the remaining array element that can be obtained by repeatedly removing a pair of array elements and replacing them by their absolute difference.

Examples:

Input: arr[] ={ 2, 7, 4, 1, 8, 1 } 
Output:
Explanation: 
Removing the pair (arr[0], arr[2]) from arr[] and inserting abs(arr[0] – arr[2]) into arr[] modifies arr[] to { 2, 7, 1, 8, 1 }. 
Removing the pair (arr[1], arr[3]) from arr[] and inserting abs(arr[1] – arr[3]) into arr[] modifies arr[] to { 2, 1, 1, 1 }. 
Removing the pair (arr[0], arr[1]) from arr[] and inserting abs(arr[0] – arr[1]) into arr[] modifies arr[] to { 1, 1, 1 }. 
Removing the pair (arr[0], arr[1]) from arr[] modifies arr[] to { 1 }. 
Therefore, the required output is 1.

Input: arr[] = { 1, 1, 4, 2, 2 } 
Output: 0

Approach: The problem can be solved using Dynamic programming based on the following observations:



Consider an array arr[] = { a, b, c, d }. 
If a > b, then removing the pair (a, b) modifies arr[] to { a – b, c, d } 
If c > d, then removing the pair (c, d) modifies arr[] to { a – b, c – d } 
If (a – b) > (c – d), then removing the pair (a – b, c – d) modifies arr[] to { (a + d) – (b + c) } 
From the above observation, it can be observed that the problem is to partition the array into two subsets with minimum difference of their subset sums
 

Following is the recurrence relation:

min_diff(i, sum) = min(min_diff(i – 1, sum + arr[i – 1]), min_diff(i – 1, sum))
where, i : index of array elements 
sum : sum of elements of the first subset 
 

Follow the steps below to solve the problem:

  • Initialize a 2D array, say dp[][], to store the minimum difference of subset sums that can be obtained upto the ith element.
  • Use the above recurrence relation and calculate the value of dp[N][sum].
  • Finally, print the value of dp[N][sum] as the required sum.

Below is the implementation of the above approach:

C++

filter_none

edit
close

play_arrow

link
brightness_4
code

// C++ program to implement
// the above approach
 
 
#include <bits/stdc++.h>
using namespace std;
 
 
// Function to find the smallest element
// left in the array by the given oprations
int smallestLeft(int arr[], int total,
     int sum, int i, vector<vector<int> > &dp)
{
     
    // Base Case
    if (i == 0) {
        return abs(total - 2 * sum);
    }
 
    // If this subproblem
    // has occurred previously
    if (dp[i][sum] != -1)
        return dp[i][sum];
 
    // Including i-th array element
    // into the first subset
    int X = smallestLeft(arr, total,
        sum + arr[i - 1], i - 1, dp);
            
    // If i-th array element is not selected               
    int Y = smallestLeft(arr, total,
                    sum, i - 1, dp);
 
     // Update dp[i][sum]
     return dp[i][sum] = min(X, Y);               
}
 
 
// Utility function to find smallest element
// left in the array by the given oprations
int UtilSmallestElement(int arr[], int N)
{
    // Stores sum of
    // the array elements
    int total = 0;
 
    // Traverse the array
    for (int i = 0; i < N; i++) {
 
        // Update total
        total += arr[i];
    }
     
     
    // Stores overlapping
    // subproblems
    vector<vector<int> > dp(N + 1,
          vector<int>(total, -1));
           
           
    cout<< smallestLeft(arr, total,
                         0, N, dp);
     
}
 
// Driver Code
int main()
{
 
    int arr[] = { 2, 7, 4, 1, 8, 1 };
     
    int N = sizeof(arr) / sizeof(arr[0]);
    UtilSmallestElement(arr, N);
    return 0;
}

chevron_right


Java

filter_none

edit
close

play_arrow

link
brightness_4
code

// Java program for above approach
import java.util.*;
import java.lang.*;
class GFG
{
 
  // Function to find the smallest element
  // left in the array by the given oprations
  static int smallestLeft(int arr[], int total,
                          int sum, int i, int[][] dp)
  {
 
    // Base Case
    if (i == 0)
    {
      return Math.abs(total - 2 * sum);
    }
 
    // If this subproblem
    // has occurred previously
    if (dp[i][sum] != -1)
      return dp[i][sum];
 
    // Including i-th array element
    // into the first subset
    int X = smallestLeft(arr, total,
                         sum + arr[i - 1], i - 1, dp);
 
    // If i-th array element is not selected               
    int Y = smallestLeft(arr, total,
                         sum, i - 1, dp);
 
    // Update dp[i][sum]
    return dp[i][sum] = Math.min(X, Y);               
  }
 
 
  // Utility function to find smallest element
  // left in the array by the given oprations
  static void UtilSmallestElement(int arr[], int N)
  {
 
    // Stores sum of
    // the array elements
    int total = 0;
 
    // Traverse the array
    for (int i = 0; i < N; i++)
    {
 
      // Update total
      total += arr[i];
    }
 
    // Stores overlapping
    // subproblems
    int[][] dp = new int[N + 1][total];
    for(int[] k:dp)
      Arrays.fill(k, -1);  
    System.out.println(smallestLeft(arr, total,
                                    0, N, dp));
  }
 
  // Driver function
  public static void main (String[] args)
  {
    int arr[] = { 2, 7, 4, 1, 8, 1 };
    int N = arr.length;
    UtilSmallestElement(arr, N);
  }
}
 
// This code is contributed by offbeat

chevron_right


Python3

filter_none

edit
close

play_arrow

link
brightness_4
code

# Python program to implement
# the above approach
 
# function to find the smallest element
# left in the array by the given oprations
def smallestLeft( arr, total, sum, i, dp):
   
    # Base Case
    if (i == 0):
        return abs(total - 2 * sum)
       
    # If this subproblem
    # has occurred previously
    if (dp[i][sum] != -1):
        return dp[i][sum]
       
    # Including i-th array element
    # into the first subset
    X = smallestLeft(arr, total, sum + arr[i - 1], i - 1, dp)
            
    # If i-th array element is not selected               
    Y = smallestLeft(arr, total, sum, i - 1, dp)
 
    #  Update dp[i][sum]
    dp[i][sum] = min(X, Y)
    return dp[i][sum]
 
# Utility function to find smallest element
# left in the array by the given oprations
def UtilSmallestElement(arr, N):
   
    # Stores sum of
    # the array elements
    total = 0
     
    # Traverse the array
    for i in range (0, N):
       
        # Update total
        total += arr[i]
     
    # Stores overlapping
    # subproblems
    dp = [[-1 for y in range(total)] for x in range(N+1)]       
    print(smallestLeft(arr, total, 0, N, dp))
 
# Driver Code
arr = [2, 7, 4, 1, 8, 1 ]
N = len(arr)
UtilSmallestElement(arr, N)
 
# This code is contributed by amreshkumar3.

chevron_right


C#

filter_none

edit
close

play_arrow

link
brightness_4
code

// C# program for above approach
using System;
public class GFG
{
 
  // Function to find the smallest element
  // left in the array by the given oprations
  static int smallestLeft(int []arr, int total,
                          int sum, int i, int[,] dp)
  {
 
    // Base Case
    if (i == 0)
    {
      return Math.Abs(total - 2 * sum);
    }
 
    // If this subproblem
    // has occurred previously
    if (dp[i,sum] != -1)
      return dp[i,sum];
 
    // Including i-th array element
    // into the first subset
    int X = smallestLeft(arr, total,
                         sum + arr[i - 1], i - 1, dp);
 
    // If i-th array element is not selected               
    int Y = smallestLeft(arr, total,
                         sum, i - 1, dp);
 
    // Update dp[i,sum]
    return dp[i,sum] = Math.Min(X, Y);               
  }
 
 
  // Utility function to find smallest element
  // left in the array by the given oprations
  static void UtilSmallestElement(int []arr, int N)
  {
 
    // Stores sum of
    // the array elements
    int total = 0;
 
    // Traverse the array
    for (int i = 0; i < N; i++)
    {
 
      // Update total
      total += arr[i];
    }
 
    // Stores overlapping
    // subproblems
    int[,] dp = new int[N + 1,total];
    for(int i = 0; i < N + 1; i++)
    {
      for (int j = 0; j < total; j++)
      {
        dp[i, j] = -1;
      }
    }
    Console.WriteLine(smallestLeft(arr, total,
                                   0, N, dp));
  }
 
  // Driver function
  public static void Main(String[] args)
  {
    int []arr = { 2, 7, 4, 1, 8, 1 };
    int N = arr.Length;
    UtilSmallestElement(arr, N);
  }
}
 
// This code is contributed by shikhasingrajput

chevron_right


Output: 

1

 

Time Complexity: O(N * sum), where sum is the sum of array elements 
Auxiliary space: O(N * sum)

Space optimized Approach: To optimize the above approach, the idea is to use tabulation method. Follow the steps below to solve the problem:

  • Initialize an array, say dp[], where dp[i] checks if the sum i can be obtained as the sum of a subset of the given array.
  • Traverse the array and calculate the sum of array elements and store it in a variable, say totalSum.
  • Using the above recurrence relation, find the closest value of (totalSum] / 2), say X, such that dp[X] is true.
  • Finally, print the value of (totalSum – 2 * X).

Below is the implementation of the above approach:

C++

filter_none

edit
close

play_arrow

link
brightness_4
code

// C++ program to implement
// the above approach
 
#include <bits/stdc++.h>
using namespace std;
 
// Function to find minimze the remaining
// array element by removing pairs and
// replacing them by their absolute difference
int SmallestElementLeft(int arr[], int N)
{
     
    // Stores sum of array elements
    int totalSum = 0;
     
    // Traverse the array
    for (int i = 0; i < N; i++) {
 
        // Update totalSum
        totalSum += arr[i];
    }
     
    // Stores half of totalSum
    int req = totalSum / 2;
     
     
    // dp[i]: True if sum i can be
// obtained as a subset sum
    bool dp[req + 1];
     
     
    // Initialize dp[] array
    memset(dp, false, sizeof(dp));
 
    // Base case          
    dp[0] = true;
 
    // Stores closest sum that can
    // be obtained as a subset sum
    int reach = 0;
     
     
    // Traverse the array
    for (int i = 0; i < N; i++) {
         
        // Iterate over all possible value of sum
        for (int j = req; j - arr[i] >= 0; j--) {
 
            // Update dp[j]
            dp[j] = dp[j] || dp[j - arr[i]];
 
            // If sum i can be obtained
            // from array elements
            if (dp[j]) {
 
                // Update reach
                reach = max(reach, j);
            }
        }
    }
 
    return totalSum - (2 * reach);
}
 
// Driver Code
int main()
{
 
    int arr[] = { 2, 2, 2 };
    int N = sizeof(arr) / sizeof(arr[0]);
     
    cout<< SmallestElementLeft(arr, N);
    return 0;
}

chevron_right


Java

filter_none

edit
close

play_arrow

link
brightness_4
code

// Java program to implement
// the above approach
import java.util.*;
    
class GFG{
    
// Function to find minimze the remaining
// array element by removing pairs and
// replacing them by their absolute difference
static int SmallestElementLeft(int arr[], int N)
{
     
    // Stores sum of array elements
    int totalSum = 0;
      
    // Traverse the array
    for(int i = 0; i < N; i++)
    {
         
        // Update totalSum
        totalSum += arr[i];
    }
      
    // Stores half of totalSum
    int req = totalSum / 2;
     
    // dp[i]: True if sum i can be
    // obtained as a subset sum
    boolean[] dp = new boolean[req + 1];
      
    // Initialize dp[] array
    Arrays.fill(dp, false);
  
    // Base case          
    dp[0] = true;
  
    // Stores closest sum that can
    // be obtained as a subset sum
    int reach = 0;
      
    // Traverse the array
    for(int i = 0; i < N; i++)
    {
         
        // Iterate over all possible value of sum
        for(int j = req; j - arr[i] >= 0; j--)
        {
             
            // Update dp[j]
            dp[j] = dp[j] || dp[j - arr[i]];
  
            // If sum i can be obtained
            // from array elements
            if (dp[j])
            {
                 
                // Update reach
                reach = Math.max(reach, j);
            }
        }
    }
    return totalSum - (2 * reach);
}
    
// Driver Code
public static void main(String[] args)
{
    int arr[] = { 2, 2, 2 };
    int N = arr.length;
     
    System.out.print(SmallestElementLeft(arr, N));
}
}
 
// This code is contributed by code_hunt

chevron_right


Python3

filter_none

edit
close

play_arrow

link
brightness_4
code

# Python3 program to implement
# the above approach
 
# Function to find minimze the remaining
# array element by removing pairs and
# replacing them by their absolute difference
def SmallestElementLeft(arr, N):
 
    # Stores sum of array elements
    totalSum = 0
 
    # Traverse the array
    for i in range(N):
 
        # Update totalSum
        totalSum += arr[i]
 
    # Stores half of totalSum
    req = totalSum // 2
 
 
    # dp[i]: True if sum i can be
# obtained as a subset sum
    dp = [False for i in range(req + 1)]
 
    # Initialize dp[] array
    # memset(dp, false, sizeof(dp));
 
    # Base case
    dp[0] = True
 
    # Stores closest sum that can
    # be obtained as a subset sum
    reach = 0
 
    # Traverse the array
    for i in range(N):
 
        # Iterate over all possible value of sum
        j = req
        while j>=arr[i]:
 
            # Update dp[j]
            dp[j] = dp[j] or dp[j - arr[i]]
 
            # If sum i can be obtained
            # from array elements
            if (dp[j]):
 
                # Update reach
                reach = max(reach, j)
            j -= 1
 
    return totalSum - (2 * reach)
 
# Driver Code
if __name__ == '__main__':
 
    arr = [2, 2, 2]
    N = len(arr)
 
    print(SmallestElementLeft(arr, N))
 
    # This code is contributed by mohit kumar 29

chevron_right


C#

filter_none

edit
close

play_arrow

link
brightness_4
code

// C# program to implement
// the above approach 
using System; 
class GFG
{
     
// Function to find minimze the remaining
// array element by removing pairs and
// replacing them by their absolute difference
static int SmallestElementLeft(int[] arr, int N)
{
      
    // Stores sum of array elements
    int totalSum = 0;
       
    // Traverse the array
    for(int i = 0; i < N; i++)
    {
          
        // Update totalSum
        totalSum += arr[i];
    }
       
    // Stores half of totalSum
    int req = totalSum / 2;
      
    // dp[i]: True if sum i can be
    // obtained as a subset sum
    bool[] dp = new bool[req + 1];
       
    // Initialize dp[] array
    for(int i = 0; i < req + 1; i++)
    {
        dp[i] = false;
    }
 
    // Base case          
    dp[0] = true;
   
    // Stores closest sum that can
    // be obtained as a subset sum
    int reach = 0;
       
    // Traverse the array
    for(int i = 0; i < N; i++)
    {
          
        // Iterate over all possible value of sum
        for(int j = req; j - arr[i] >= 0; j--)
        {
              
            // Update dp[j]
            dp[j] = dp[j] || dp[j - arr[i]];
   
            // If sum i can be obtained
            // from array elements
            if (dp[j])
            {
                  
                // Update reach
                reach = Math.Max(reach, j);
            }
        }
    }
    return totalSum - (2 * reach);
}
     
// Driver Code
public static void Main()
{
    int[] arr = { 2, 2, 2 };
    int N = arr.Length;    
    Console.Write(SmallestElementLeft(arr, N));
}
}
 
// This code is contributed by sanjoy_62.

chevron_right


Output:

2

Time Complexity: O(N * sum), where sum is the sum of array elements 
Auxiliary space: O(sum)

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.

My Personal Notes arrow_drop_up
Recommended Articles
Page :