Open In App

Minimum removals required such that sum of remaining array modulo M is X

Last Updated : 24 Apr, 2023
Improve
Improve
Like Article
Like
Save
Share
Report

Given an array arr[] consisting of N positive integers and the integers X and M, where 0 <= X < M, the task is to find the minimum number of elements required to be removed such that sum of the remaining array modulo M is equal to X. Print -1 if not possible.

Examples: 

Input: arr[] = {3, 2, 1, 2}, M = 4, X = 2
Output: 1
Explanation: One of the elements at indices (0-based) 1 or 3 can be removed. If arr[1] is removed, then arr[] modifies to {3, 1, 2} and sum % M = 6 % 4 = 2 which is equal to X = 2.

Input: arr[] = {3, 2, 1, 3}, M = 4, X = 3
Output: 1
Explanation: Remove element arr[1]( = 2). Therefore, arr[] modifies to {3, 1, 3} and sum % M = 7 % 4 = 3 which is equal to X = 3. 

Naive Approach: The simplest approach is to generate all possible subsets of the given array and for each subset, check if sum modulo M of the array after removal of the subset is equal to X or not. If found to be true, store its size. Print minimum size among all such subsets obtained.

Time Complexity: O(2N) where N is the length of the given array.
Auxiliary Space: O(N)

Efficient Approach: To optimize the above approach, the idea is to use dynamic programming based on the following observations:

  • If S % M > X, then the minimum number of elements having sum S % M – X must be removed from the array to make the sum modulo M equal to X.
  • Otherwise, the minimum number of elements having sum S % M + M – X must be removed to make the sum modulo M equal to X.

Follow the steps below to solve the problem: 

  • Initialize a dp[] table, table[N + 1][X + 1] where table[i][j] represents the minimum number of elements to remove having indices in the range [0, i] such that their sum is j where X is the sum so be removed.
  • Initialize dp[0][i] for each i in the range [1, X] with some large value.
  • The dp transitions are as follows:

dp[i][j] = min(dp[i-1][j], dp[i][j-arr[i-1]]+1) 
where, i is in the range [1, N] and j is in the range [1, X].

  • Print dp[N][X] as the minimum elements to be removed.

Below is the implementation of the above approach:

C++




// C++ program for the above approach
#include <bits/stdc++.h>
using namespace std;
 
// Function to find the minimum
// elements having sum x
int findSum(vector<int> S, int n, int x)
{
 
    // Initialize dp table
    vector<vector<int> > table(n + 1,
                               vector<int>(
                                   x + 1, 0));
 
    for (int i = 1; i <= x; i++) {
        table[0][i] = INT_MAX - 1;
    }
 
    // Pre-compute subproblems
    for (int i = 1; i <= n; i++) {
 
        for (int j = 1; j <= x; j++) {
 
            // If mod is smaller than element
            if (S[i - 1] > j) {
                table[i][j] = table[i - 1][j];
            }
            else {
 
                // Minimum elements with sum
                // j upto index i
                table[i][j]
                    = min(table[i - 1][j],
                          table[i][j
                                   - S[i - 1]]
                              + 1);
            }
        }
    }
 
    // Return answer
    return (table[n][x] > n)
               ? -1
               : table[n][x];
}
 
// Function to find minimum number
// of removals to make sum % M in
// remaining array is equal to X
void minRemovals(vector<int> arr,
                 int n, int m, int x)
{
 
    // Sum of all elements
    int sum = 0;
    for (int i = 0; i < n; i++) {
        sum += arr[i];
    }
 
    // Sum to be removed
    int requied_Sum = 0;
 
    if (sum % m < x)
        requied_Sum
            = m + sum % m - x;
    else
        requied_Sum
            = sum % m - x;
 
    // Print answer
    cout << findSum(arr, n,
                    requied_Sum);
}
 
// Driver Code
int main()
{
 
    // Given array
    vector<int> arr = { 3, 2, 1, 2 };
 
    // Given size
    int n = arr.size();
 
    // Given mod and x
    int m = 4, x = 2;
 
    // Function call
    minRemovals(arr, n, m, x % m);
 
    return 0;
}


Java




// Java program for the above approach
import java.util.*;
 
class GFG{
 
// Function to find the minimum
// elements having sum x
static int findSum(int[] S, int n, int x)
{
     
    // Initialize dp table
    int [][]table = new int[n + 1][x + 1];
     
    for(int i = 1; i <= x; i++)
    {
        table[0][i] = Integer.MAX_VALUE - 1;
    }
 
    // Pre-compute subproblems
    for(int i = 1; i <= n; i++)
    {
        for(int j = 1; j <= x; j++)
        {
             
            // If mod is smaller than element
            if (S[i - 1] > j)
            {
                table[i][j] = table[i - 1][j];
            }
            else
            {
                 
                // Minimum elements with sum
                // j upto index i
                table[i][j] = Math.min(table[i - 1][j],
                                       table[i][j - S[i - 1]] + 1);
            }
        }
    }
 
    // Return answer
    return (table[n][x] > n) ? -1 : table[n][x];
}
 
// Function to find minimum number
// of removals to make sum % M in
// remaining array is equal to X
static void minRemovals(int[] arr, int n,
                        int m, int x)
{
     
    // Sum of all elements
    int sum = 0;
    for(int i = 0; i < n; i++)
    {
        sum += arr[i];
    }
 
    // Sum to be removed
    int requied_Sum = 0;
 
    if (sum % m < x)
        requied_Sum = m + sum % m - x;
    else
        requied_Sum = sum % m - x;
 
    // Print answer
    System.out.print(findSum(arr, n,
                             requied_Sum));
}
 
// Driver Code
public static void main(String[] args)
{
     
    // Given array
    int[] arr = { 3, 2, 1, 2 };
 
    // Given size
    int n = arr.length;
 
    // Given mod and x
    int m = 4, x = 2;
 
    // Function call
    minRemovals(arr, n, m, x % m);
}
}
 
// This code is contributed by Amit Katiyar


Python3




# Python3 program for the above approach
import sys
 
# Function to find the minimum
# elements having sum x
def findSum(S, n, x):
     
    # Initialize dp table
    table = [[0 for x in range(x + 1)]
                for y in range(n + 1)]
 
    for i in range(1, x + 1):
        table[0][i] = sys.maxsize - 1
 
    # Pre-compute subproblems
    for i in range(1, n + 1):
        for j in range(1, x + 1):
 
            # If mod is smaller than element
            if (S[i - 1] > j):
                table[i][j] = table[i - 1][j]
 
            else:
 
                # Minimum elements with sum
                # j upto index i
                table[i][j] = min(table[i - 1][j],
                                  table[i][j - S[i - 1]] + 1)
                                   
    # Return answer
    if (table[n][x] > n):
        return -1
         
    return table[n][x]
 
# Function to find minimum number
# of removals to make sum % M in
# remaining array is equal to X
def minRemovals(arr, n, m, x):
     
    # Sum of all elements
    sum = 0
    for i in range(n):
        sum += arr[i]
 
    # Sum to be removed
    requied_Sum = 0
 
    if (sum % m < x):
        requied_Sum = m + sum % m - x
    else:
        requied_Sum = sum % m - x
 
    # Print answer
    print(findSum(arr, n,
                  requied_Sum))
 
# Driver Code
if __name__ == "__main__":
 
    # Given array
    arr = [ 3, 2, 1, 2 ]
 
    # Given size
    n = len(arr)
 
    # Given mod and x
    m = 4
    x = 2
 
    # Function call
    minRemovals(arr, n, m, x % m)
 
# This code is contributed by chitranayal


C#




// C# program for the
// above approach
using System;
class GFG{
 
// Function to find the minimum
// elements having sum x
static int findSum(int[] S,
                   int n, int x)
{   
  // Initialize dp table
  int [,]table = new int[n + 1,
                         x + 1];
 
  for(int i = 1; i <= x; i++)
  {
    table[0, i] = int.MaxValue - 1;
  }
 
  // Pre-compute subproblems
  for(int i = 1; i <= n; i++)
  {
    for(int j = 1; j <= x; j++)
    {
 
      // If mod is smaller than
      // element
      if (S[i - 1] > j)
      {
        table[i, j] = table[i - 1, j];
      }
      else
      {
 
        // Minimum elements with sum
        // j upto index i
        table[i, j] = Math.Min(table[i - 1, j],
                              table[i, j -
                              S[i - 1]] + 1);
      }
    }
  }
 
  // Return answer
  return (table[n, x] > n) ? -1 :
          table[n, x];
}
 
// Function to find minimum number
// of removals to make sum % M in
// remaining array is equal to X
static void minRemovals(int[] arr, int n,
                        int m, int x)
{   
  // Sum of all elements
  int sum = 0;
  for(int i = 0; i < n; i++)
  {
    sum += arr[i];
  }
 
  // Sum to be removed
  int requied_Sum = 0;
 
  if (sum % m < x)
    requied_Sum = m + sum %
                  m - x;
  else
    requied_Sum = sum % m - x;
 
  // Print answer
  Console.Write(findSum(arr, n,
                        requied_Sum));
}
 
// Driver Code
public static void Main(String[] args)
{   
  // Given array
  int[] arr = {3, 2, 1, 2};
 
  // Given size
  int n = arr.Length;
 
  // Given mod and x
  int m = 4, x = 2;
 
  // Function call
  minRemovals(arr, n, m, x % m);
}
}
 
// This code is contributed by Amit Katiyar


Javascript




<script>
 
// JavaScript program to implement
// the above approach
 
// Function to find the minimum
// elements having sum x
function findSum(S, n, x)
{
      
    // Initialize dp table
    let table = new Array(n + 1);
      
    // Loop to create 2D array using 1D array
    for (var i = 0; i < table.length; i++) {
        table[i] = new Array(2);
    }
     
    for (var i = 0; i < table.length; i++) {
        for (var j = 0; j < table.length; j++) {
        table[i][j] = 0;
    }
    }
      
    for(let i = 1; i <= x; i++)
    {
        table[0][i] = Number.MAX_VALUE - 1;
    }
  
    // Pre-compute subproblems
    for(let i = 1; i <= n; i++)
    {
        for(let j = 1; j <= x; j++)
        {
              
            // If mod is smaller than element
            if (S[i - 1] > j)
            {
                table[i][j] = table[i - 1][j];
            }
            else
            {
                  
                // Minimum elements with sum
                // j upto index i
                table[i][j] = Math.min(table[i - 1][j],
                              table[i][j - S[i - 1]] + 1);
            }
        }
    }
  
    // Return answer
    return (table[n][x] > n) ? -1 : table[n][x];
}
  
// Function to find minimum number
// of removals to make sum % M in
// remaining array is equal to X
function minRemovals(arr, n, m, x)
{
      
    // Sum of all elements
    let sum = 0;
    for(let i = 0; i < n; i++)
    {
        sum += arr[i];
    }
  
    // Sum to be removed
    let requied_Sum = 0;
  
    if (sum % m < x)
        requied_Sum = m + sum % m - x;
    else
        requied_Sum = sum % m - x;
  
    // Print answer
   document.write(findSum(arr, n,
                          requied_Sum));
}
 
// Driver Code
 
      // Given array
    let arr = [ 3, 2, 1, 2 ];
  
    // Given size
    let n = arr.length;
  
    // Given mod and x
    let m = 4, x = 2;
  
    // Function call
    minRemovals(arr, n, m, x % m);
           
</script>


Output

1

Time Complexity: O(N*X) where N is the length of the given array and X is the given integer.
Auxiliary Space: O(N*X) 

Efficient approach : Space optimization

In previous approach we use 2d matrix to store the computation of subproblems but the current computation is only depend upon the previous row and con current row so to optimize the space complexity we use a 1D vector of size X+1 to get the computation of previous row.

Implementation steps :

  • Create a vectors table of size x+1 to store previous row computation of matrix.
  • For setting the Base Case initialize the table with INT_MAX – 1.
  • Now iterate over subproblem and store the current with the help of table.
  • Update the current value of table previous computations.
  • At last check if answer exists and return table[x] else return -1.
     

Implementation:

C++




// C++ program for the above approach
#include <bits/stdc++.h>
using namespace std;
 
// Function to find the minimum
// elements having sum x
int findSum(vector<int> S, int n, int x)
{
 
    // Initialize dp table
    vector<int> table(x + 1, 0);
 
    for (int i = 1; i <= x; i++) {
        table[i] = INT_MAX - 1;
    }
 
    // Pre-compute subproblems
    for (int i = 1; i <= n; i++) {
 
        for (int j = x; j >= 1; j--) {
 
            // If mod is smaller than element
            if (S[i - 1] > j) {
                continue;
            }
            else {
 
                // Minimum elements with sum
                // j upto index i
                table[j] = min(table[j],
                          table[j - S[i - 1]]
                              + 1);
            }
        }
    }
 
    // Return answer
    return (table[x] > n)
               ? -1
               : table[x];
}
 
// Function to find minimum number
// of removals to make sum % M in
// remaining array is equal to X
void minRemovals(vector<int> arr,
                 int n, int m, int x)
{
 
    // Sum of all elements 
    int sum = 0;
    for (int i = 0; i < n; i++) {
        sum += arr[i];
    }
 
    // Sum to be removed
    int requied_Sum = 0;
 
    if (sum % m < x)
        requied_Sum
            = m + sum % m - x;
    else
        requied_Sum
            = sum % m - x;
 
    // Print answer
    cout << findSum(arr, n,
                    requied_Sum);
}
 
// Driver Code
int main()
{
 
    // Given array
    vector<int> arr = { 3, 2, 1, 2 };
 
    // Given size
    int n = arr.size();
 
    // Given mod and x
    int m = 4, x = 2;
 
    // Function call
    minRemovals(arr, n, m, x % m);
 
    return 0;
}
 
// this code is contributed by bhardwajji


Java




import java.util.*;
 
class Main {
    // Function to find the minimum
    // elements having sum x
    public static int findSum(List<Integer> S, int n, int x) {
 
        // Initialize dp table
        int[] table = new int[x + 1];
        Arrays.fill(table, Integer.MAX_VALUE - 1);
        table[0] = 0;
 
        // Pre-compute subproblems
        for (int i = 1; i <= n; i++) {
            for (int j = x; j >= 1; j--) {
 
                // If mod is smaller than element
                if (S.get(i - 1) > j) {
                    continue;
                } else {
 
                    // Minimum elements with sum
                    // j upto index i
                    table[j] = Math.min(table[j],
                              table[j - S.get(i - 1)]
                                  + 1);
                }
            }
        }
 
        // Return answer
        return (table[x] > n) ? -1 : table[x];
    }
 
    // Function to find minimum number
    // of removals to make sum % M in
    // remaining array is equal to X
    public static void minRemovals(List<Integer> arr,
                                    int n, int m, int x) {
 
        // Sum of all elements 
        int sum = 0;
        for (int i = 0; i < n; i++) {
            sum += arr.get(i);
        }
 
        // Sum to be removed
        int required_Sum = 0;
        if (sum % m < x) {
            required_Sum = m + sum % m - x;
        } else {
            required_Sum = sum % m - x;
        }
 
        // Print answer
        System.out.println(findSum(arr, n, required_Sum));
    }
 
    // Driver code
    public static void main(String[] args) {
 
        // Given array
        List<Integer> arr = new ArrayList<>();
        arr.add(3);
        arr.add(2);
        arr.add(1);
        arr.add(2);
 
        // Given size
        int n = arr.size();
 
        // Given mod and x
        int m = 4, x = 2;
 
        // Function call
        minRemovals(arr, n, m, x % m);
    }
}


Python3




# Function to find the minimum
# elements having sum x
def findSum(S, n, x):
 
    # Initialize dp table
    table = [0] * (x + 1)
    for i in range(1, x+1):
        table[i] = float('inf')
 
    # Pre-compute subproblems
    for i in range(1, n+1):
        for j in range(x, 0, -1):
 
            # If mod is smaller than element
            if S[i - 1] > j:
                continue
            else:
                # Minimum elements with sum
                # j upto index i
                table[j] = min(table[j], table[j - S[i - 1]] + 1)
 
    # Return answer
    return -1 if table[x] > n else table[x]
 
# Function to find minimum number
# of removals to make sum % M in
# remaining array is equal to X
def minRemovals(arr, n, m, x):
 
    # Sum of all elements 
    sum_arr = sum(arr)
 
    # Sum to be removed
    required_sum = (m + sum_arr % m - x) % m if sum_arr % m < x else (sum_arr % m - x)
 
    # Print answer
    print(findSum(arr, n, required_sum))
 
# Driver Code
if __name__ == '__main__':
 
    # Given array
    arr = [3, 2, 1, 2]
 
    # Given size
    n = len(arr)
 
    # Given mod and x
    m = 4
    x = 2
 
    # Function call
    minRemovals(arr, n, m, x % m)


C#




using System;
 
class GFG {
    // Function to find the minimum
    // elements having sum x
    static int FindSum(int[] S, int n, int x)
    {
        // Initialize dp table
        int[] table = new int[x + 1];
        for (int i = 1; i <= x; i++)
            table[i] = int.MaxValue - 1;
        // Pre-compute subproblems
        for (int i = 1; i <= n; i++) {
            for (int j = x; j >= 1; j--) {
                // If mod is smaller than element
                if (S[i - 1] > j)
                    continue;
                else {
                    // Minimum elements with sum
                    // j upto index i
                    table[j] = Math.Min(
                        table[j], table[j - S[i - 1]] + 1);
                }
            }
        }
 
        // Return answer
        return (table[x] > n) ? -1 : table[x];
    }
 
    // Function to find minimum number
    // of removals to make sum % M in
    // remaining array is equal to X
    static void MinRemovals(int[] arr, int n, int m, int x)
    {
        // Sum of all elements
        int sum = 0;
        for (int i = 0; i < n; i++)
            sum += arr[i];
 
        // Sum to be removed
        int required_sum = 0;
 
        if (sum % m < x)
            required_sum = m + sum % m - x;
        else
            required_sum = sum % m - x;
 
        // Print answer
        Console.WriteLine(FindSum(arr, n, required_sum));
    }
 
    // Driver Code
    public static void Main()
    {
        // Given array
        int[] arr = { 3, 2, 1, 2 };
 
        // Given size
        int n = arr.Length;
 
        // Given mod and x
        int m = 4, x = 2;
 
        // Function call
        MinRemovals(arr, n, m, x % m);
    }
}
// This code is contributed by sarojmcy2e


Javascript




// Function to find the minimum
// elements having sum x
function findSum(S, n, x) {
    // Initialize dp table
    let table = new Array(x + 1).fill(0);
    for (let i = 1; i <= x; i++) {
        table[i] = Number.MAX_SAFE_INTEGER - 1;
    }
    // Pre-compute subproblems
    for (let i = 1; i <= n; i++) {
        for (let j = x; j >= 1; j--) {
            // If mod is smaller than element
            if (S[i - 1] > j) {
                continue;
            } else {
                // Minimum elements with sum
                // j upto index i
                table[j] = Math.min(table[j], table[j - S[i - 1]] + 1);
            }
        }
    }
    // Return answer
    return table[x] > n ? -1 : table[x];
}
 
// Function to find minimum number
// of removals to make sum % M in
// remaining array is equal to X
function minRemovals(arr, n, m, x) {
    // Sum of all elements 
    let sum = arr.reduce((a, b) => a + b, 0);
    // Sum to be removed
    let requiredSum = sum % m < x ? m + sum % m - x : sum % m - x;
    // Print answer
    console.log(findSum(arr, n, requiredSum));
}
 
let arr = [3, 2, 1, 2];
let n = arr.length;
let m = 4;
let x = 2;
 
minRemovals(arr, n, m, x % m);


Output

1

Time Complexity: O(N*X) 
Auxiliary Space: O(X) 



Like Article
Suggest improvement
Previous
Next
Share your thoughts in the comments

Similar Reads