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); 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); } } // 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) # 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); } } // This code is contributed by Amit Katiyar |
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)
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.