Minimize rows to be made zero for last column sum to be at most any one column
Given an N * M matrix mat[][] consisting of non-negative integers. In one operation, select any row and change all elements to 0. The task is to find the minimum number of operations required such that the sum of elements in the Mth column is less than or equal to the sum of elements in jth column for at least one ‘j’ ( where 1 ≤ ‘j’ ≤ ‘M’-1).
Examples:
Input: N = 3, M = 3, mat[][] = [ [3, 1, 2], [2, 3, 5], [3, 1, 2] ]
Output: 1
Explanation: Initially, sum of elements in each columns, S = [8, 5, 9].
If we operate on the second row, the updated array of sums S = [6, 2, 4], where S[3] < S[1].
Hence we need at least one operation.
Input: N = 3, M=3, MAT[][] = [[3, 2, 6], [ 1, 2, 3 ], [5, 1, 9] ]
Output: 3
Explanation: The only possible way is to make all the elements in the matrix as 0.
i.e, perform one operation on each row. After these operations S[0] = S[1] = S[2].
Return 3 as final answer.
Naive approach: The simplest approach is to try all possible combinations of rows and make them and check for each combination if the condition is satisfied or not.
- Operate on some number of rows, and the simplest way is to try with all possible combinations of rows.
- There are ‘N‘ rows in the matrix, so there will be a total of (2 ^ N) ways for the selection of rows to be operated.
- Generate all the possible combinations and for each of them, do the following:
- Create a copy ‘tmp‘ of the original matrix mat[][].
- Count the number of rows in each combination and mark all the elements in corresponding rows as 0 (in ‘tmp‘ only).
- Find the sum of elements in the Mth column, let it be ‘sumM’.
- Compute the sum in each column (from 1 to ‘M-1’), and if the sum of any of these columns is greater or equal to the Mth column, consider the number of rows as one of the answers.
- Among all the combinations, return the smallest size (minimum number of rows) for which we found at least one column having a sum greater or equal to the Mth column.
Below is the implementation of the above approach :
C++
#include <bits/stdc++.h>
using namespace std;
int countMinOp( int n, int m, vector<vector< int > >& mat)
{
int ans = n;
for ( int i = 0; i < (1 << n); i++) {
vector<vector< int > > tmp = mat;
int cnt = 0;
for ( int j = 0; j < n; j++) {
if (((i >> j) & 1) == 1) {
cnt++;
for ( int k = 0; k < m; k++) {
tmp[j][k] = 0;
}
}
}
int sumM = 0;
bool flag = false ;
for ( int j = 0; j < n; j++) {
sumM += tmp[j][m - 1];
}
for ( int j = 0; j < m - 1; j++) {
int sum = 0;
for ( int k = 0; k < n; k++) {
sum += tmp[k][j];
}
if (sum >= sumM) {
flag = true ;
break ;
}
}
if (flag == true ) {
ans = min(ans, cnt);
}
}
return ans;
}
int main()
{
int N = 3;
int M = 3;
vector<vector< int > > mat
= { { 3, 1, 2 }, { 2, 3, 5 }, { 3, 1, 2 } };
cout << countMinOp(N, M, mat);
return 0;
}
|
Java
import java.util.*;
public class GFG {
static int countMinOp( int n, int m, int mat[][])
{
int ans = n;
for ( int i = 0 ; i < ( 1 << n); i++) {
int tmp[][] = mat;
int cnt = 0 ;
for ( int j = 0 ; j < n; j++) {
if (((i >> j) & 1 ) == 1 ) {
cnt++;
for ( int k = 0 ; k < m; k++) {
tmp[j][k] = 0 ;
}
}
}
int sumM = 0 ;
boolean flag = false ;
for ( int j = 0 ; j < n; j++) {
sumM += tmp[j][m - 1 ];
}
for ( int j = 0 ; j < m - 1 ; j++) {
int sum = 0 ;
for ( int k = 0 ; k < n; k++) {
sum += tmp[k][j];
}
if (sum >= sumM) {
flag = true ;
break ;
}
}
if (flag == true ) {
ans = Math.min(ans, cnt);
}
}
return ans;
}
public static void main(String args[])
{
int N = 3 ;
int M = 3 ;
int mat[][]
= { { 3 , 1 , 2 }, { 2 , 3 , 5 }, { 3 , 1 , 2 } };
System.out.print(countMinOp(N, M, mat));
}
}
|
Python3
def countMinOp(n, m, mat) :
ans = n
for i in range ( 0 , ( 1 << n)):
tmp = mat
cnt = 0
for j in range ( 0 , n):
if (((i >> j) & 1 ) = = 1 ) :
cnt + = 1
for j in range ( 0 , m):
tmp[j][k] = 0
sumM = 0
flag = False
for j in range ( 0 , n):
sumM + = tmp[j][m - 1 ]
for j in range ( 0 , m - 1 ):
sum = 0
for k in range ( 0 , n):
sum + = tmp[k][j]
if ( sum > = sumM) :
flag = True
break
if (flag = = True ) :
ans = min (ans, cnt)
return ans
N = 3
M = 3
mat = [[ 3 , 1 , 2 ], [ 2 , 3 , 5 ], [ 3 , 1 , 2 ]]
print (countMinOp(N, M, mat))
|
C#
using System;
class GFG {
static int countMinOp( int n, int m, int [,]mat)
{
int ans = n;
for ( int i = 0; i < (1 << n); i++) {
int [,]tmp = mat;
int cnt = 0;
for ( int j = 0; j < n; j++) {
if (((i >> j) & 1) == 1) {
cnt++;
for ( int k = 0; k < m; k++) {
tmp[j,k] = 0;
}
}
}
int sumM = 0;
bool flag = false ;
for ( int j = 0; j < n; j++) {
sumM += tmp[j,m - 1];
}
for ( int j = 0; j < m - 1; j++) {
int sum = 0;
for ( int k = 0; k < n; k++) {
sum += tmp[k,j];
}
if (sum >= sumM) {
flag = true ;
break ;
}
}
if (flag == true ) {
ans = Math.Min(ans, cnt);
}
}
return ans;
}
public static void Main()
{
int N = 3;
int M = 3;
int [,]mat
= { { 3, 1, 2 }, { 2, 3, 5 }, { 3, 1, 2 } };
Console.Write(countMinOp(N, M, mat));
}
}
|
Javascript
<script>
function countMinOp(n, m, mat) {
let ans = n;
for (let i = 0; i < (1 << n); i++) {
let tmp = [...mat];
let cnt = 0;
for (let j = 0; j < n; j++) {
if (((i >> j) & 1) == 1) {
cnt++;
for (let k = 0; k < m; k++) {
tmp[j][k] = 0;
}
}
}
let sumM = 0;
let flag = false ;
for (let j = 0; j < n; j++) {
sumM += tmp[j][m - 1];
}
for (let j = 0; j < m - 1; j++) {
let sum = 0;
for (let k = 0; k < n; k++) {
sum += tmp[k][j];
}
if (sum >= sumM) {
flag = true ;
break ;
}
}
if (flag == true ) {
ans = Math.min(ans, cnt);
}
}
return ans;
}
let N = 3;
let M = 3;
let mat
= [[3, 1, 2], [2, 3, 5], [3, 1, 2]];
document.write(countMinOp(N, M, mat));
</script>
|
Time Complexity: O((2N) * N * M)
Auxiliary Space: O(N * M)
Efficient Approach: The basic idea of the efficient approach is based on the concept that we need at least one column for which the sum of elements is not smaller than the final column. So, solve the problem for a fixed column and repeat each column. Follow the steps mentioned below to solve the problem:
- Consider two arrays, ‘A1’ and ‘A2’, both of length ‘N’ where the array ‘A1’ denotes any column among 1 to ‘M’-1 and the array ‘A2’ denotes the Mth column.
- We erase some indices from both arrays such that the sum of remaining elements in ‘A1’ is not smaller than ‘A2’, i.e., Sum(A1) >= Sum(A2).
- For the deletion part, it is optimal to delete such an index for which (‘A1[i]’ – ‘A2[i]’) is more negative among all the indices.
- If (‘A1[i]’ – ‘A2[i]’) is non-negative, we don’t need to delete this index at all.
- Take the most negative one because we may or may not delete an index where (‘A1[i]’ – ‘A2[i]’) is negative. Taking an example if A1 = [3, 1, 4] and A2 = [2, 3, 2]. Here, (A1[2] – A2[2]) is negative but we don’t delete this because other elements are taking care of the total sum.
- To perform the above task optimally:
- create an array ‘diff’ that contains all the corresponding elements’ differences, i.e., ‘A1[i]’ – ‘A2[i]’.
- Sort the array ‘diff’ in decreasing order of elements.
- Take the longest prefix until the prefix-sum is non-negative and the rest of the elements need to be deleted.
- Repeat the above process for each column and consider the minimum number of elements that need to be deleted.
Below is the implementation of the above approach.
C++
#include <bits/stdc++.h>
using namespace std;
int countMinOp( int n, int m,
vector<vector< int > >& mat)
{
int ans = n;
for ( int i = 0; i < m - 1; i++) {
vector< int > diff;
for ( int j = 0; j < n; j++) {
diff.push_back(mat[j][i]
- mat[j][m - 1]);
}
sort(diff.begin(), diff.end(),
greater< int >());
int sum = 0, k = 0;
while ((k < n) and (sum + diff[k]
>= 0)) {
sum += diff[k];
k++;
}
ans = min(ans, n - k);
}
return ans;
}
int main()
{
int N = 3;
int M = 3;
vector<vector< int > > mat
= { { 3, 1, 2 }, { 2, 3, 5 }, { 3, 1, 2 } };
cout << countMinOp(N, M, mat);
return 0;
}
|
Java
import java.util.*;
class GFG {
public static int
countMinOp( int n, int m,
ArrayList<ArrayList<Integer> > mat)
{
int ans = n;
for ( int i = 0 ; i < m - 1 ; i++) {
ArrayList<Integer> diff
= new ArrayList<Integer>();
for ( int j = 0 ; j < n; j++) {
diff.add(mat.get(j).get(i)
- mat.get(j).get(m - 1 ));
}
Collections.sort(diff,
Collections.reverseOrder());
int sum = 0 , k = 0 ;
while ((k < n) && (sum + diff.get(k) >= 0 )) {
sum += diff.get(k);
k++;
}
ans = Math.min(ans, n - k);
}
return ans;
}
public static void main(String[] args)
{
int N = 3 ;
int M = 3 ;
ArrayList<ArrayList<Integer> > mat
= new ArrayList<ArrayList<Integer> >();
ArrayList<Integer> temp1 = new ArrayList<Integer>(
Arrays.asList( 3 , 1 , 2 ));
ArrayList<Integer> temp2 = new ArrayList<Integer>(
Arrays.asList( 2 , 3 , 5 ));
ArrayList<Integer> temp3 = new ArrayList<Integer>(
Arrays.asList( 3 , 1 , 2 ));
mat.add(temp1);
mat.add(temp2);
mat.add(temp3);
System.out.print(countMinOp(N, M, mat));
}
}
|
Python3
def countMinOp(n, m, mat):
ans = n
for i in range (m - 1 ):
diff = []
for j in range (n):
diff.append(mat[j][i]
- mat[j][m - 1 ])
diff.sort(reverse = True )
sum = 0
k = 0
while ((k < n) and ( sum + diff[k]
> = 0 )):
sum + = diff[k]
k + = 1
ans = min (ans, n - k)
return ans
if __name__ = = "__main__" :
N = 3
M = 3
mat = [[ 3 , 1 , 2 ], [ 2 , 3 , 5 ], [ 3 , 1 , 2 ]]
print (countMinOp(N, M, mat))
|
C#
using System;
using System.Linq;
using System.Collections.Generic;
class GFG
{
static int
countMinOp( int n, int m,
List<List< int > > mat)
{
int ans = n;
for ( int i = 0; i < m - 1; i++) {
List< int > diff
= new List< int >();
diff.Add(-3);
diff.Add(1);
diff.Add(-1);
diff.Add(-2);
diff.Add(-1);
diff.Sort();
diff.Reverse();
int sum = 0, k = 0;
while ((k < n) && (sum + diff[k] >= 0)) {
sum += diff[k];
k++;
}
ans = Math.Min(ans, n - k);
}
return ans;
}
public static void Main()
{
int N = 3;
int M = 3;
List<List< int > > mat
= new List<List< int > >();
List< int > temp1 = new List< int >();
temp1.Add(3);temp1.Add(1);temp1.Add(2);
List< int > temp2 = new List< int >();
temp2.Add(2);temp2.Add(3);temp2.Add(5);
List< int > temp3 = new List< int >();
temp3.Add(3);temp3.Add(1);temp3.Add(2);
mat.Add(temp1);
mat.Add(temp2);
mat.Add(temp3);
Console.Write(countMinOp(N, M, mat));
}
}
|
Javascript
<script>
function countMinOp(n, m, mat)
{
let ans = n;
for (let i = 0; i < m - 1; i++) {
let diff = [];
for (let j = 0; j < n; j++) {
diff.push(mat[j][i]
- mat[j][m - 1]);
}
diff.sort((a,b)=>b-a);
let sum = 0, k = 0;
while ((k < n) && (sum + diff[k] >= 0)) {
sum += diff[k];
k++;
}
ans = Math.min(ans, n - k);
}
return ans;
}
let N = 3;
let M = 3;
let mat = [ [ 3, 1, 2 ],[ 2, 3, 5 ],[ 3, 1, 2] ];
document.write(countMinOp(N, M, mat));
</script>
|
Time Complexity: O(N * M * logN)
Auxiliary Space: O(N)
Last Updated :
05 Apr, 2022
Like Article
Save Article
Share your thoughts in the comments
Please Login to comment...