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++
#include <bits/stdc++.h>
using namespace std;
int findSum(vector< int > S, int n, int x)
{
vector<vector< int > > table(n + 1,
vector< int >(
x + 1, 0));
for ( int i = 1; i <= x; i++) {
table[0][i] = INT_MAX - 1;
}
for ( int i = 1; i <= n; i++) {
for ( int j = 1; j <= x; j++) {
if (S[i - 1] > j) {
table[i][j] = table[i - 1][j];
}
else {
table[i][j]
= min(table[i - 1][j],
table[i][j
- S[i - 1]]
+ 1);
}
}
}
return (table[n][x] > n)
? -1
: table[n][x];
}
void minRemovals(vector< int > arr,
int n, int m, int x)
{
int sum = 0;
for ( int i = 0; i < n; i++) {
sum += arr[i];
}
int requied_Sum = 0;
if (sum % m < x)
requied_Sum
= m + sum % m - x;
else
requied_Sum
= sum % m - x;
cout << findSum(arr, n,
requied_Sum);
}
int main()
{
vector< int > arr = { 3, 2, 1, 2 };
int n = arr.size();
int m = 4, x = 2;
minRemovals(arr, n, m, x % m);
return 0;
}
|
Java
import java.util.*;
class GFG{
static int findSum( int [] S, int n, int x)
{
int [][]table = new int [n + 1 ][x + 1 ];
for ( int i = 1 ; i <= x; i++)
{
table[ 0 ][i] = Integer.MAX_VALUE - 1 ;
}
for ( int i = 1 ; i <= n; i++)
{
for ( int j = 1 ; j <= x; j++)
{
if (S[i - 1 ] > j)
{
table[i][j] = table[i - 1 ][j];
}
else
{
table[i][j] = Math.min(table[i - 1 ][j],
table[i][j - S[i - 1 ]] + 1 );
}
}
}
return (table[n][x] > n) ? - 1 : table[n][x];
}
static void minRemovals( int [] arr, int n,
int m, int x)
{
int sum = 0 ;
for ( int i = 0 ; i < n; i++)
{
sum += arr[i];
}
int requied_Sum = 0 ;
if (sum % m < x)
requied_Sum = m + sum % m - x;
else
requied_Sum = sum % m - x;
System.out.print(findSum(arr, n,
requied_Sum));
}
public static void main(String[] args)
{
int [] arr = { 3 , 2 , 1 , 2 };
int n = arr.length;
int m = 4 , x = 2 ;
minRemovals(arr, n, m, x % m);
}
}
|
Python3
import sys
def findSum(S, n, x):
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
for i in range ( 1 , n + 1 ):
for j in range ( 1 , x + 1 ):
if (S[i - 1 ] > j):
table[i][j] = table[i - 1 ][j]
else :
table[i][j] = min (table[i - 1 ][j],
table[i][j - S[i - 1 ]] + 1 )
if (table[n][x] > n):
return - 1
return table[n][x]
def minRemovals(arr, n, m, x):
sum = 0
for i in range (n):
sum + = arr[i]
requied_Sum = 0
if ( sum % m < x):
requied_Sum = m + sum % m - x
else :
requied_Sum = sum % m - x
print (findSum(arr, n,
requied_Sum))
if __name__ = = "__main__" :
arr = [ 3 , 2 , 1 , 2 ]
n = len (arr)
m = 4
x = 2
minRemovals(arr, n, m, x % m)
|
C#
using System;
class GFG{
static int findSum( int [] S,
int n, int x)
{
int [,]table = new int [n + 1,
x + 1];
for ( int i = 1; i <= x; i++)
{
table[0, i] = int .MaxValue - 1;
}
for ( int i = 1; i <= n; i++)
{
for ( int j = 1; j <= x; j++)
{
if (S[i - 1] > j)
{
table[i, j] = table[i - 1, j];
}
else
{
table[i, j] = Math.Min(table[i - 1, j],
table[i, j -
S[i - 1]] + 1);
}
}
}
return (table[n, x] > n) ? -1 :
table[n, x];
}
static void minRemovals( int [] arr, int n,
int m, int x)
{
int sum = 0;
for ( int i = 0; i < n; i++)
{
sum += arr[i];
}
int requied_Sum = 0;
if (sum % m < x)
requied_Sum = m + sum %
m - x;
else
requied_Sum = sum % m - x;
Console.Write(findSum(arr, n,
requied_Sum));
}
public static void Main(String[] args)
{
int [] arr = {3, 2, 1, 2};
int n = arr.Length;
int m = 4, x = 2;
minRemovals(arr, n, m, x % m);
}
}
|
Javascript
<script>
function findSum(S, n, x)
{
let table = new Array(n + 1);
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;
}
for (let i = 1; i <= n; i++)
{
for (let j = 1; j <= x; j++)
{
if (S[i - 1] > j)
{
table[i][j] = table[i - 1][j];
}
else
{
table[i][j] = Math.min(table[i - 1][j],
table[i][j - S[i - 1]] + 1);
}
}
}
return (table[n][x] > n) ? -1 : table[n][x];
}
function minRemovals(arr, n, m, x)
{
let sum = 0;
for (let i = 0; i < n; i++)
{
sum += arr[i];
}
let requied_Sum = 0;
if (sum % m < x)
requied_Sum = m + sum % m - x;
else
requied_Sum = sum % m - x;
document.write(findSum(arr, n,
requied_Sum));
}
let arr = [ 3, 2, 1, 2 ];
let n = arr.length;
let m = 4, x = 2;
minRemovals(arr, n, m, x % m);
</script>
|
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++
#include <bits/stdc++.h>
using namespace std;
int findSum(vector< int > S, int n, int x)
{
vector< int > table(x + 1, 0);
for ( int i = 1; i <= x; i++) {
table[i] = INT_MAX - 1;
}
for ( int i = 1; i <= n; i++) {
for ( int j = x; j >= 1; j--) {
if (S[i - 1] > j) {
continue ;
}
else {
table[j] = min(table[j],
table[j - S[i - 1]]
+ 1);
}
}
}
return (table[x] > n)
? -1
: table[x];
}
void minRemovals(vector< int > arr,
int n, int m, int x)
{
int sum = 0;
for ( int i = 0; i < n; i++) {
sum += arr[i];
}
int requied_Sum = 0;
if (sum % m < x)
requied_Sum
= m + sum % m - x;
else
requied_Sum
= sum % m - x;
cout << findSum(arr, n,
requied_Sum);
}
int main()
{
vector< int > arr = { 3, 2, 1, 2 };
int n = arr.size();
int m = 4, x = 2;
minRemovals(arr, n, m, x % m);
return 0;
}
|
Java
import java.util.*;
class Main {
public static int findSum(List<Integer> S, int n, int x) {
int [] table = new int [x + 1 ];
Arrays.fill(table, Integer.MAX_VALUE - 1 );
table[ 0 ] = 0 ;
for ( int i = 1 ; i <= n; i++) {
for ( int j = x; j >= 1 ; j--) {
if (S.get(i - 1 ) > j) {
continue ;
} else {
table[j] = Math.min(table[j],
table[j - S.get(i - 1 )]
+ 1 );
}
}
}
return (table[x] > n) ? - 1 : table[x];
}
public static void minRemovals(List<Integer> arr,
int n, int m, int x) {
int sum = 0 ;
for ( int i = 0 ; i < n; i++) {
sum += arr.get(i);
}
int required_Sum = 0 ;
if (sum % m < x) {
required_Sum = m + sum % m - x;
} else {
required_Sum = sum % m - x;
}
System.out.println(findSum(arr, n, required_Sum));
}
public static void main(String[] args) {
List<Integer> arr = new ArrayList<>();
arr.add( 3 );
arr.add( 2 );
arr.add( 1 );
arr.add( 2 );
int n = arr.size();
int m = 4 , x = 2 ;
minRemovals(arr, n, m, x % m);
}
}
|
Python3
def findSum(S, n, x):
table = [ 0 ] * (x + 1 )
for i in range ( 1 , x + 1 ):
table[i] = float ( 'inf' )
for i in range ( 1 , n + 1 ):
for j in range (x, 0 , - 1 ):
if S[i - 1 ] > j:
continue
else :
table[j] = min (table[j], table[j - S[i - 1 ]] + 1 )
return - 1 if table[x] > n else table[x]
def minRemovals(arr, n, m, x):
sum_arr = sum (arr)
required_sum = (m + sum_arr % m - x) % m if sum_arr % m < x else (sum_arr % m - x)
print (findSum(arr, n, required_sum))
if __name__ = = '__main__' :
arr = [ 3 , 2 , 1 , 2 ]
n = len (arr)
m = 4
x = 2
minRemovals(arr, n, m, x % m)
|
C#
using System;
class GFG {
static int FindSum( int [] S, int n, int x)
{
int [] table = new int [x + 1];
for ( int i = 1; i <= x; i++)
table[i] = int .MaxValue - 1;
for ( int i = 1; i <= n; i++) {
for ( int j = x; j >= 1; j--) {
if (S[i - 1] > j)
continue ;
else {
table[j] = Math.Min(
table[j], table[j - S[i - 1]] + 1);
}
}
}
return (table[x] > n) ? -1 : table[x];
}
static void MinRemovals( int [] arr, int n, int m, int x)
{
int sum = 0;
for ( int i = 0; i < n; i++)
sum += arr[i];
int required_sum = 0;
if (sum % m < x)
required_sum = m + sum % m - x;
else
required_sum = sum % m - x;
Console.WriteLine(FindSum(arr, n, required_sum));
}
public static void Main()
{
int [] arr = { 3, 2, 1, 2 };
int n = arr.Length;
int m = 4, x = 2;
MinRemovals(arr, n, m, x % m);
}
}
|
Javascript
function findSum(S, n, x) {
let table = new Array(x + 1).fill(0);
for (let i = 1; i <= x; i++) {
table[i] = Number.MAX_SAFE_INTEGER - 1;
}
for (let i = 1; i <= n; i++) {
for (let j = x; j >= 1; j--) {
if (S[i - 1] > j) {
continue ;
} else {
table[j] = Math.min(table[j], table[j - S[i - 1]] + 1);
}
}
}
return table[x] > n ? -1 : table[x];
}
function minRemovals(arr, n, m, x) {
let sum = arr.reduce((a, b) => a + b, 0);
let requiredSum = sum % m < x ? m + sum % m - x : sum % m - x;
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);
|
Time Complexity: O(N*X)
Auxiliary Space: O(X)
Feeling lost in the world of random DSA topics, wasting time without progress? It's time for a change! Join our DSA course, where we'll guide you on an exciting journey to master DSA efficiently and on schedule.
Ready to dive in? Explore our Free Demo Content and join our DSA course, trusted by over 100,000 geeks!
Last Updated :
24 Apr, 2023
Like Article
Save Article