Open In App

Length of longest subset consisting of A 0s and B 1s from an array of strings

Last Updated : 16 Nov, 2024
Summarize
Comments
Improve
Suggest changes
Share
Like Article
Like
Report

Given an array arr[] consisting of binary strings, and two integers a and b, the task is to find the length of the longest subset consisting of at most a 0s and b 1s.

Examples:

Input: arr[] = ["1" ,"0" ,"0001" ,"10" ,"111001"], a = 5, b = 3
Output: 4
Explanation: 
One possible way is to select the subset [arr[0], arr[1], arr[2], arr[3]].
Total number of 0s and 1s in all these strings are 5 and 3 respectively.
Also, 4 is the length of the longest subset possible.

Input: arr[] = ["0" ,"1" ,"10"], a = 1, b = 1
Output: 2
Explanation: 
One possible way is to select the subset [arr[0], arr[1]].
Total number of 0s and 1s in all these strings is 1 and 1 respectively.
Also, 2 is the length of the longest subset possible.

Using Recursion – O(2^n) Time and O(n) Space

A simple approach is to consider all the possible subsets of strings and calculating the total counts of zeros and ones in each subset. Consider the only subsets that contain exactly a zeros and b ones. From all such subsets, pick the subset with maximum length.

Case 1: Exclude the current string

  • findMaxSubset(index, a, b) = findMaxSubset(index + 1, a, b)

Case 2: Include the current string: Include the current string in the subset if its count of zeros and ones is within the remaining limits (a and b)

  • findMaxSubset(index, a, b) = 1 + findMaxSubset(index + 1, a- zeroCount, b - oneCount), where zeroCount and oneCount is the count of zeros and ones of current string.
C++
// C++ program to find the length of the longest subset
// using recursion

#include <iostream>
#include <vector>
using namespace std;

int findMaxSubsetSize(int index, int n, vector<int>
				&zeroCounts, vector<string> &strs, int maxZeros, int maxOnes) {

    // Base case: if we've processed all strings, return 0
    if (index >= n)
        return 0;

    // Option 1: Skip the current string
    int maxSubset = findMaxSubsetSize(index + 1, 
				n, zeroCounts, strs, maxZeros, maxOnes);

    int zeroCount = zeroCounts[index];
    int oneCount = strs[index].size() - zeroCount;

    // Option 2: Include the current string if it
    // doesn't exceed the max zeros and ones allowed
    if (zeroCount <= maxZeros && oneCount <= maxOnes) {
        int includeCurrent =
            1 + findMaxSubsetSize(index + 1, n, zeroCounts, 
			strs, maxZeros - zeroCount, maxOnes - oneCount);
        maxSubset = max(maxSubset, includeCurrent);
    }

    return   maxSubset;
}

int maxSubsetSize(vector<string> &strs, int maxZeros,
                  int maxOnes) {
    int n = strs.size();

    // Precompute the count of zeros
    // in each string and store in zeroCounts array
    vector<int> zeroCounts(n, 0);
    for (int i = 0; i < n; i++) {
        int countZeros = 0;
        for (char c : strs[i]) {
            if (c == '0')
                countZeros++;
        }
        zeroCounts[i] = countZeros;
    }
    return findMaxSubsetSize(0, n, zeroCounts, strs, 
                             maxZeros, maxOnes);
}

int main() {
  
    vector<string> arr = {"1", "0", "0001", "10", "111001"};
    int a = 5, b = 3;
    int res = maxSubsetSize(arr, a, b);
    cout << res;
    return 0;
}
Java
// Java program to find the length of the longest subset
// using recursion

import java.util.*;
class GfG {
    static int findMaxSubsetSize(int index, int n,
                             int[] zeroCounts,
                             String[] strs, int maxZeros,
                             int maxOnes) {

        // Base case: if we've processed all strings, return
        // 0
        if (index >= n)
            return 0;

        // Option 1: Skip the current string
        int maxSubset
            = findMaxSubsetSize(index + 1, n, zeroCounts, strs,
                            maxZeros, maxOnes);

        int zeroCount = zeroCounts[index];
        int oneCount = strs[index].length() - zeroCount;

        // Option 2: Include the current string if it
        // doesn't exceed the max zeros and ones allowed
        if (zeroCount <= maxZeros && oneCount <= maxOnes) {
            int includeCurrent
                = 1
                  + findMaxSubsetSize(index + 1, n, zeroCounts,
                                  strs,
                                  maxZeros - zeroCount,
                                  maxOnes - oneCount);
            maxSubset = Math.max(maxSubset, includeCurrent);
        }
        return maxSubset;
    }

    static int maxSubsetSize(String[] strs, int maxZeros,
                           int maxOnes) {
        int n = strs.length;
  
        // Precompute the count of zeros in each string and
        // store in zeroCounts array
        int[] zeroCounts = new int[n];
        for (int i = 0; i < n; i++) {
            int countZeros = 0;
            for (char c : strs[i].toCharArray()) {
                if (c == '0')
                    countZeros++;
            }
            zeroCounts[i] = countZeros;
        }

        // Start the recursive helper function from the
        // first string
        return findMaxSubsetSize(0, n, zeroCounts, strs,
                             maxZeros, maxOnes);
    }

    public static void main(String[] args) {

        String[] arr = { "1", "0", "0001", "10", "111001" };
        int a = 5, b = 3;
        int res = maxSubsetSize(arr, a, b);
        System.out.println(res);
    }
}
Python
# Python program to find the length of the longest subset
# using recursion
from typing import List

def findMaxSubsetSize(index: int, n: int, zeroCounts: List[int],\
                      strs: List[str], maxZeros: int, maxOnes: int) -> int:
  
    # Base case: if we've processed all strings, return 0
    if index >= n:
        return 0

    # Option 1: Skip the current string
    maxSubset = findMaxSubsetSize(index + 1, n, \
                                  zeroCounts, strs, maxZeros, maxOnes)

    zeroCount = zeroCounts[index]
    oneCount = len(strs[index]) - zeroCount

    # Option 2: Include the current string if it doesn't 
    # exceed the max zeros and ones allowed
    if zeroCount <= maxZeros and oneCount <= maxOnes:
        includeCurrent = 1 + findMaxSubsetSize(index + 1, n, \
		zeroCounts, strs, maxZeros - zeroCount, maxOnes - oneCount)
        maxSubset = max(maxSubset, includeCurrent)

    return maxSubset

def maxSubsetSize(strs: List[str], maxZeros: int, maxOnes: int) -> int:
    n = len(strs)

    # Precompute the count of zeros in each 
    # string and store in zeroCounts array
    zeroCounts = [s.count('0') for s in strs]

    # Start the recursive helper function 
    # from the first string
    return findMaxSubsetSize(0, n, zeroCounts, strs, maxZeros, maxOnes)

arr = ["1", "0", "0001", "10", "111001"]
a, b = 5, 3
res = maxSubsetSize(arr, a, b)
print(res)
C#
// C# program to find the length of the longest subset
// using recursion

using System;

class GfG {
    static int findMaxSubsetSize(int index, int n,
                             int[] zeroCounts,
                             string[] strs, int maxZeros,
                             int maxOnes) {
      
        // Base case: if we've processed all strings, return
        // 0
        if (index >= n)
            return 0;
 
        // Option 1: Skip the current string
        int maxSubset
            = findMaxSubsetSize(index + 1, n, zeroCounts, strs,
                            maxZeros, maxOnes);

        int zeroCount = zeroCounts[index];
        int oneCount = strs[index].Length - zeroCount;

        // Option 2: Include the current string if it
        // doesn't exceed the max zeros and ones allowed
        if (zeroCount <= maxZeros && oneCount <= maxOnes) {
            int includeCurrent
                = 1
                  + findMaxSubsetSize(index + 1, n, zeroCounts,
                                  strs,
                                  maxZeros - zeroCount,
                                  maxOnes - oneCount);
            maxSubset = Math.Max(maxSubset, includeCurrent);
        }

      
        return maxSubset;
    }

    static int maxSubsetSize(string[] strs, int maxZeros,
                           int maxOnes) {
        int n = strs.Length;
 

        // Precompute the count of zeros in each string and
        // store in zeroCounts array
        int[] zeroCounts = new int[n];
        for (int i = 0; i < n; i++) {
            int countZeros = 0;
            foreach(char c in strs[i]) {
                if (c == '0')
                    countZeros++;
            }
            zeroCounts[i] = countZeros;
        }

        // Start the recursive helper function from the
        // first string
        return findMaxSubsetSize(0, n, zeroCounts, strs,
                             maxZeros, maxOnes);
    }

    static void Main() {
        string[] arr = { "1", "0", "0001", "10", "111001" };
        int a = 5, b = 3;
        int res = maxSubsetSize(arr, a, b);
        Console.WriteLine(res);
    }
}
JavaScript
// JavaScript program to find the length of the longest
// subset using recursion

function findMaxSubsetSize(index, n, zeroCounts, strs, maxZeros,
                       maxOnes) {
                       
    // Base case: if we've processed all strings, return 0
    if (index >= n) {
        return 0;
    }

   
    // Option 1: Skip the current string
    let maxSubset
        = findMaxSubsetSize(index + 1, n, zeroCounts, strs,
                        maxZeros, maxOnes);

    let zeroCount = zeroCounts[index];
    let oneCount = strs[index].length - zeroCount;

    // Option 2: Include the current string if it doesn't
    // exceed the max zeros and ones allowed
    if (zeroCount <= maxZeros && oneCount <= maxOnes) {
        let includeCurrent
            = 1
              + findMaxSubsetSize(index + 1, n, zeroCounts,
                              strs, maxZeros - zeroCount,
                              maxOnes - oneCount);
        maxSubset = Math.max(maxSubset, includeCurrent);
    }

  
    return maxSubset;
}

function maxSubsetSize(strs, maxZeros, maxOnes) {
    const n = strs.length;
 
    // Precompute the count of zeros in each string and
    // store in zeroCounts array
    const zeroCounts
        = strs.map(str => str.split("0").length - 1);

    // Start the recursive helper function from the first
    // string
    return findMaxSubsetSize(0, n, zeroCounts, strs, maxZeros,
                         maxOnes);
}

const arr = [ "1", "0", "0001", "10", "111001" ];
const a = 5, b = 3;
const res = maxSubsetSize(arr, a, b);
console.log(res);

Output
4

Using Memoization - O(n*a*b) Time and O(n*a*b) Space

If we notice carefully, we can observe that the above recursive solution holds the following two properties of Dynamic Programming.

1. Optimal Substructure: The solution to the problem of finding the maximum subset of strings that satisfy exactly a zeros and b ones can be derived from the optimal solutions of smaller subproblems.

2. Overlapping Subproblems: When implementing a recursive approach to solve the problem of selecting strings with exactly a zeros and b ones, we observe that many subproblems are computed multiple times. Specifically, when we recursively solve for findMaxSubset(index, a, b), where a and b represent the remaining number of zeros and ones, the same subproblems might be recomputed several times.

  • The recursive solution involves changing three parameters: the current index and the remaining count of zeros (a) and remaining count of ones (b). We need to track these three parameters, so we create a 3D array of size (n+1)x(a+1)x(b+1) because the value of n will be in range of [0, n] and remaining count of a will be in range [0, a] and remaining count of b will be in range [0, b].
  • We initialize the 3D array with -1 to indicate that no subproblems have been computed yet.
  • we check if the value at memo[n][a][b] is -1. if it is, we proceed to compute the result. otherwise, we return the stored result.
C++
// C++ program to find the length of the longest subset
// using memoization

#include <iostream>
#include <vector>
using namespace std;

int findMaxSubsetSize(int index, int n, vector<int> &zeroCounts, 
                      vector<string> &strs, int maxZeros, int maxOnes,
                  vector<vector<vector<int>>> &memo) {

    // Base case: if we've processed all strings, return 0
    if (index >= n)
        return 0;

    // if this state has already
    //  been computed, return its stored result
    if (memo[index][maxZeros][maxOnes] != -1)
        return memo[index][maxZeros][maxOnes];

    // Option 1: Skip the current string
    int maxSubset = findMaxSubsetSize(index + 1, n, 
                                      zeroCounts, strs, 
                                      maxZeros, maxOnes, memo);

    int zeroCount = zeroCounts[index];
    int oneCount = strs[index].size() - zeroCount;

    // Option 2: Include the current string if it
    // doesn't exceed the max zeros and ones allowed
    if (zeroCount <= maxZeros && oneCount <= maxOnes) {
        int includeCurrent =
            1 + findMaxSubsetSize(index + 1, n, 
			zeroCounts, strs, maxZeros - zeroCount, maxOnes - oneCount, memo);
        maxSubset = max(maxSubset, includeCurrent);
    }

    // Memoize the result for the current state and return it
    return memo[index][maxZeros][maxOnes] = maxSubset;
}

int maxSubsetSize(vector<string> &strs, int maxZeros, int maxOnes) {
    int n = strs.size();

    // 3D DP array to memoize results,
    // initialized to -1 for uncomputed states
    vector<vector<vector<int>>> memo(n + 1,
	vector<vector<int>>(maxZeros + 1, vector<int>(maxOnes + 1, -1)));

    // Precompute the count of zeros
    // in each string and store in zeroCounts array
    vector<int> zeroCounts(n, 0);
    for (int i = 0; i < n; i++) {
        int countZeros = 0;
        for (char c : strs[i]) {
            if (c == '0')
                countZeros++;
        }
        zeroCounts[i] = countZeros;
    }
    return findMaxSubsetSize(0, n, zeroCounts, 
                             strs, maxZeros, maxOnes, memo);
}

int main() {
  
    vector<string> arr = {"1", "0", "0001", "10", "111001"};
    int a = 5, b = 3;
    int res = maxSubsetSize(arr, a, b);
    cout << res;
    return 0;
}
Java
// Java program to find the length of the longest subset
// using memoization

import java.util.*;

class GfG {
    static int findMaxSubsetSize(int index, int n,
                             int[] zeroCounts,
                             String[] strs, int maxZeros,
                             int maxOnes, int[][][] memo) {

        // Base case: if we've processed all strings, return
        // 0
        if (index >= n)
            return 0;

        // Memoization check: if this state has already been
        // computed, return its stored result
        if (memo[index][maxZeros][maxOnes] != -1)
            return memo[index][maxZeros][maxOnes];

        // Option 1: Skip the current string
        int maxSubset
            = findMaxSubsetSize(index + 1, n, zeroCounts, strs,
                            maxZeros, maxOnes, memo);

        int zeroCount = zeroCounts[index];
        int oneCount = strs[index].length() - zeroCount;

        // Option 2: Include the current string if it
        // doesn't exceed the max zeros and ones allowed
        if (zeroCount <= maxZeros && oneCount <= maxOnes) {
            int includeCurrent
                = 1
                  + findMaxSubsetSize(index + 1, n, zeroCounts,
                                  strs,
                                  maxZeros - zeroCount,
                                  maxOnes - oneCount, memo);
            maxSubset = Math.max(maxSubset, includeCurrent);
        }

        // Memoize the result for the current state and
        // return it
        memo[index][maxZeros][maxOnes] = maxSubset;
        return maxSubset;
    }

    static int maxSubsetSize(String[] strs, int maxZeros,
                           int maxOnes) {
        int n = strs.length;

        // 3D DP array to memoize results, initialized to -1
        // for uncomputed states
        int[][][] memo
            = new int[n + 1][maxZeros + 1][maxOnes + 1];
        for (int i = 0; i <= n; i++) {
            for (int j = 0; j <= maxZeros; j++) {
                Arrays.fill(memo[i][j], -1);
            }
        }

        // Precompute the count of zeros in each string and
        // store in zeroCounts array
        int[] zeroCounts = new int[n];
        for (int i = 0; i < n; i++) {
            int countZeros = 0;
            for (char c : strs[i].toCharArray()) {
                if (c == '0')
                    countZeros++;
            }
            zeroCounts[i] = countZeros;
        }

        // Start the recursive helper function from the
        // first string
        return findMaxSubsetSize(0, n, zeroCounts, strs,
                             maxZeros, maxOnes, memo);
    }

    public static void main(String[] args) {

        String[] arr = { "1", "0", "0001", "10", "111001" };
        int a = 5, b = 3;
        int res = maxSubsetSize(arr, a, b);
        System.out.println(res);
    }
}
Python
# Python program to find the length of the longest subset
# using memoization

from typing import List


def findMaxSubsetSize(index: int, n: int, zeroCounts: \
                      List[int], strs: List[str], maxZeros: int,\
                      maxOnes: int, memo: List[List[List[int]]]) -> int:
  
    # Base case: if we've processed all strings, return 0
    if index >= n:
        return 0

    # Memoization check: if this state has 
    # already been computed, return its stored result
    if memo[index][maxZeros][maxOnes] != -1:
        return memo[index][maxZeros][maxOnes]

    # Option 1: Skip the current string
    maxSubset = findMaxSubsetSize(index + 1, n, zeroCounts,
                              strs, maxZeros, maxOnes, memo)

    zeroCount = zeroCounts[index]
    oneCount = len(strs[index]) - zeroCount

    # Option 2: Include the current string if it doesn't 
    # exceed the max zeros and ones allowed
    if zeroCount <= maxZeros and oneCount <= maxOnes:
        includeCurrent = 1 + \
            findMaxSubsetSize(index + 1, n, zeroCounts, strs,
                          maxZeros - zeroCount, maxOnes - oneCount, memo)
        maxSubset = max(maxSubset, includeCurrent)

    # Memoize the result for the current state and return it
    memo[index][maxZeros][maxOnes] = maxSubset
    return maxSubset


def maxSubsetSize(strs: List[str], maxZeros: int, maxOnes: int) -> int:
    n = len(strs)

    # 3D DP array to memoize results, 
    # initialized to -1 for uncomputed states
    memo = [[[-1] * (maxOnes + 1) for _ in range(maxZeros + 1)]
          for _ in range(n + 1)]

    # Precompute the count of zeros in each 
    # string and store in zeroCounts array
    zeroCounts = [s.count('0') for s in strs]

    # Start the recursive helper function 
    # from the first string
    return findMaxSubsetSize(0, n, zeroCounts, strs, maxZeros, maxOnes, memo)


arr = ["1", "0", "0001", "10", "111001"]
a, b = 5, 3
res = maxSubsetSize(arr, a, b);
print(res)
C#
// C# program to find the length of the longest subset
// using memoization

using System;

class GfG {
    static int findMaxSubsetSize(int index, int n,
                             int[] zeroCounts,
                             string[] strs, int maxZeros,
                             int maxOnes, int[, , ] memo) {
      
        // Base case: if we've processed all strings, return
        // 0
        if (index >= n)
            return 0;

        // Memoization check: if this state has already been
        // computed, return its stored result
        if (memo[index, maxZeros, maxOnes] != -1)
            return memo[index, maxZeros, maxOnes];

        // Option 1: Skip the current string
        int maxSubset
            = findMaxSubsetSize(index + 1, n, zeroCounts, strs,
                            maxZeros, maxOnes, memo);

        int zeroCount = zeroCounts[index];
        int oneCount = strs[index].Length - zeroCount;

        // Option 2: Include the current string if it
        // doesn't exceed the max zeros and ones allowed
        if (zeroCount <= maxZeros && oneCount <= maxOnes) {
            int includeCurrent
                = 1
                  + findMaxSubsetSize(index + 1, n, zeroCounts,
                                  strs,
                                  maxZeros - zeroCount,
                                  maxOnes - oneCount, memo);
            maxSubset = Math.Max(maxSubset, includeCurrent);
        }

        // Memoize the result for the current state and
        // return it
        memo[index, maxZeros, maxOnes] = maxSubset;
        return maxSubset;
    }

    static int maxSubsetSize(string[] strs, int maxZeros,
                           int maxOnes) {
        int n = strs.Length;

        // 3D DP array to memoize results, initialized to -1
        // for uncomputed states
        int[, , ] memo
            = new int[n + 1, maxZeros + 1, maxOnes + 1];
        for (int i = 0; i <= n; i++)
            for (int j = 0; j <= maxZeros; j++)
                for (int k = 0; k <= maxOnes; k++)
                    memo[i, j, k] = -1;

        // Precompute the count of zeros in each string and
        // store in zeroCounts array
        int[] zeroCounts = new int[n];
        for (int i = 0; i < n; i++) {
            int countZeros = 0;
            foreach(char c in strs[i]) {
                if (c == '0')
                    countZeros++;
            }
            zeroCounts[i] = countZeros;
        }

        // Start the recursive helper function from the
        // first string
        return findMaxSubsetSize(0, n, zeroCounts, strs,
                             maxZeros, maxOnes, memo);
    }

    public static void Main() {
        string[] arr = { "1", "0", "0001", "10", "111001" };
        int a = 5, b = 3;
        int res = maxSubsetSize(arr, a, b);
        Console.WriteLine(res);
    }
}
JavaScript
// JavaScript program to find the length of the longest
// subset using memoization

function findMaxSubsetSize(index, n, zeroCounts, strs, maxZeros,
                       maxOnes, memo) {

    // Base case: if we've processed all strings, return 0
    if (index >= n) {
        return 0;
    }

    // Memoization check: if this state has already been
    // computed, return its stored result
    if (memo[index][maxZeros][maxOnes] !== -1) {
        return memo[index][maxZeros][maxOnes];
    }

    // Option 1: Skip the current string
    let maxSubset
        = findMaxSubsetSize(index + 1, n, zeroCounts, strs,
                        maxZeros, maxOnes, memo);

    let zeroCount = zeroCounts[index];
    let oneCount = strs[index].length - zeroCount;

    // Option 2: Include the current string if it doesn't
    // exceed the max zeros and ones allowed
    if (zeroCount <= maxZeros && oneCount <= maxOnes) {
        let includeCurrent
            = 1
              + findMaxSubsetSize(index + 1, n, zeroCounts,
                              strs, maxZeros - zeroCount,
                              maxOnes - oneCount, memo);
        maxSubset = Math.max(maxSubset, includeCurrent);
    }

    // Memoize the result for the current state and return
    // it
    memo[index][maxZeros][maxOnes] = maxSubset;
    return maxSubset;
}

function maxSubsetSize(strs, maxZeros, maxOnes) {
    const n = strs.length;

    // 3D DP array to memoize results, initialized to -1 for
    // uncomputed states
    const memo = Array.from(
        {length : n + 1},
        () => Array.from(
            {length : maxZeros + 1},
            () => Array(maxOnes + 1).fill(-1)));

    // Precompute the count of zeros in each string and
    // store in zeroCounts array
    const zeroCounts
        = strs.map(str => str.split("0").length - 1);

    // Start the recursive helper function from the first
    // string
    return findMaxSubsetSize(0, n, zeroCounts, strs, maxZeros,
                         maxOnes, memo);
}

const arr = [ "1", "0", "0001", "10", "111001" ];
const a = 5, b = 3;
const res = maxSubsetSize(arr, a, b);
console.log(res);

Output
4

Using Bottom-Up DP (Tabulation) - O(n*a*b) Time and O(n*a*b) Space

The approach is similar to the previous one. just instead of breaking down the problem recursively, we iteratively build up the solution by calculating in bottom-up manner where dp[i][j][k] represent the maximum size of the subset of the first i strings that can be formed using at most j zeros and k ones.

Base Case:

if i = 0, j = 0, k = 0
dp[i][j][k] = 0

Recurrance relations:

if zeros[i-1] > j or ones[i-1] > k
dp[i][j][k] = dp[i-1][j][k]

else
dp[i][j][k] = max(dp[i-1][j][k], 1 + dp[i-1][j-zeros[i-1]][k-ones[i-1]]) here, zeros[i-1] and ones[i-1] is the number of zeros and ones, respectively, in the (i-1)th string.

C++
// C++ program to find the length of the longest subset
// using tabulation

#include <algorithm>
#include <iostream>
#include <vector>
using namespace std;

int maxSubsetSize(vector<string> &strs, int maxZeros, int maxOnes) {
    int n = strs.size();

    // 3D DP array to store results
    vector<vector<vector<int>>> dp(n + 1, vector<vector<int>>
	(maxZeros + 1, vector<int>(maxOnes + 1, 0)));

    // Precompute the count of zeros in each string
    // and store in zeroCounts array
    vector<int> zeroCounts(n, 0);
    for (int i = 0; i < n; i++) {
        int countZeros = 0;
        for (char c : strs[i]) {
            if (c == '0')
                countZeros++;
        }
        zeroCounts[i] = countZeros;
    }

    // Fill the DP table
    for (int i = 1; i <= n; i++) {
        for (int j = 0; j <= maxZeros; j++) {
            for (int k = 0; k <= maxOnes; k++) {
              
                // Option 1: Don't include the current string
                dp[i][j][k] = dp[i - 1][j][k];

                // Option 2: Include the current string if it doesn't exceed
                // the max zeros and ones
                int zeroCount = zeroCounts[i - 1];
                int oneCount = strs[i - 1].size() - zeroCount;

                if (zeroCount <= j && oneCount <= k) {
                    dp[i][j][k] = max(dp[i][j][k], 1 + dp[i - 1][j - zeroCount][k - oneCount]);
                }
            }
        }
    }

    // Return the result from the DP table
    return dp[n][maxZeros][maxOnes];
}

int main() {
    vector<string> arr = {"1", "0", "0001", "10", "111001"};
    int a = 5, b = 3;
    int res = maxSubsetSize(arr, a, b);
    cout << res;
    return 0;
}
Java
// Java program to find the length of the longest subset
// using Tabulation

import java.util.*;

class GfG {

      static int maxSubsetSize(List<String> strs,
                                    int maxZeros,
                                    int maxOnes) {
        int n = strs.size();

        // 3D DP array to store results
        int[][][] dp
            = new int[n + 1][maxZeros + 1][maxOnes + 1];

        // Precompute the count of zeros in each string and
        // store in zeroCounts array
        int[] zeroCounts = new int[n];
        for (int i = 0; i < n; i++) {
            int countZeros = 0;
            for (char c : strs.get(i).toCharArray()) {
                if (c == '0')
                    countZeros++;
            }
            zeroCounts[i] = countZeros;
        }

        // Fill the DP table
        for (int i = 1; i <= n; i++) {
            for (int j = 0; j <= maxZeros; j++) {
                for (int k = 0; k <= maxOnes; k++) {
                  
                    // Option 1: Don't include the current
                    // string
                    dp[i][j][k] = dp[i - 1][j][k];

                    // Option 2: Include the current string
                    // if it doesn't exceed the max zeros
                    // and ones
                    int zeroCount = zeroCounts[i - 1];
                    int oneCount = strs.get(i - 1).length()
                                   - zeroCount;

                    if (zeroCount <= j && oneCount <= k) {
                        dp[i][j][k] = Math.max(
                            dp[i][j][k],
                            1
                                + dp[i - 1][j - zeroCount]
                                    [k - oneCount]);
                    }
                }
            }
        }

        // Return the result from the DP table
        return dp[n][maxZeros][maxOnes];
    }

    public static void main(String[] args) {
        List<String> arr = Arrays.asList("1", "0", "0001",
                                         "10", "111001");
        int a = 5, b = 3;
        int res = maxSubsetSize(arr, a, b);
        System.out.println(res);
    }
}
Python
# Python program to find the length of the longest subset
# using Tabulation


def maxSubsetSize(strs, maxZeros, maxOnes):
    n = len(strs)

    # 3D DP array to store results
    dp = [[[0] * (maxOnes + 1) for _ in range(maxZeros + 1)]
          for _ in range(n + 1)]

    # Precompute the count of zeros in each
    # string and store in zeroCounts array
    zeroCounts = [0] * n
    for i in range(n):
        countZeros = strs[i].count('0')
        zeroCounts[i] = countZeros

    # Fill the DP table
    for i in range(1, n + 1):
        for j in range(maxZeros + 1):
            for k in range(maxOnes + 1):
              
                # Option 1: Don't include the current string
                dp[i][j][k] = dp[i - 1][j][k]

                # Option 2: Include the current string if
                # it doesn't exceed the max zeros and ones
                zeroCount = zeroCounts[i - 1]
                oneCount = len(strs[i - 1]) - zeroCount

                if zeroCount <= j and oneCount <= k:
                    dp[i][j][k] = max(dp[i][j][k], 1 + dp[i - 1]
                                      [j - zeroCount][k - oneCount])

    # Return the result from the DP table
    return dp[n][maxZeros][maxOnes]


if __name__ == "__main__":
    arr = ["1", "0", "0001", "10", "111001"]
    a, b = 5, 3
    res = maxSubsetSize(arr, a, b)
    print(res)
C#
// C# program to find the length of the longest subset
// using Tabulation
using System;
using System.Linq;

class GfG {
  
    // Function to calculate the maximum subset size
    static int maxSubsetSize(string[] strs, int maxZeros, int maxOnes) {
      
        int n = strs.Length;

        // 3D DP array to store the results
        int[, ,] dp = new int[n + 1, maxZeros + 1, maxOnes + 1];

        // Precompute the count of zeros in each 
      	// string and store in zeroCounts array
        int[] zeroCounts = new int[n];
        for (int i = 0; i < n; i++) {
            zeroCounts[i] = strs[i].Count(c => c == '0');
        }

        // Fill the DP table
        for (int i = 1; i <= n; i++) {
            for (int j = 0; j <= maxZeros; j++) {
                for (int k = 0; k <= maxOnes; k++) {
                  
                    // Option 1: Don't include the current string
                    dp[i, j, k] = dp[i - 1, j, k];

                    // Option 2: Include the current string if
                  	// it doesn't exceed the max zeros and ones
                    int zeroCount = zeroCounts[i - 1];
                    int oneCount = strs[i - 1].Length - zeroCount;

                    if (zeroCount <= j && oneCount <= k) {
                        dp[i, j, k] = Math.Max(dp[i, j, k],
                            1 + dp[i - 1, j - zeroCount, k - oneCount]);
                    }
                }
            }
        }

        // Return the result from the DP table (maximum subset size)
        return dp[n, maxZeros, maxOnes];
    }

    static void Main() {
    
        string[] arr = { "1", "0", "0001", "10", "111001" };

        int a = 5, b = 3;
        int res = maxSubsetSize(arr, a, b);
        Console.WriteLine(res);  
    }
}
JavaScript
// JavaScript program to find the length of the longest
// subset using Tabulation

function maxSubsetSize(strs, maxZeros, maxOnes) {

    const n = strs.length;

    // 3D DP array to store results
    const dp = Array.from(
        {length : n + 1},
        () => Array.from({length : maxZeros + 1},
                         () => Array(maxOnes + 1).fill(0)));

    // Precompute the count of zeros in each string and
    // store in zeroCounts array
    const zeroCounts = strs.map(
        str => str.split("").filter(c => c === "0").length);

    // Fill the DP table
    for (let i = 1; i <= n; i++) {
        for (let j = 0; j <= maxZeros; j++) {
            for (let k = 0; k <= maxOnes; k++) {

                // Option 1: Don't include the current
                // string
                dp[i][j][k] = dp[i - 1][j][k];

                // Option 2: Include the current string if
                // it doesn't exceed the max zeros and ones
                const zeroCount = zeroCounts[i - 1];
                const oneCount
                    = strs[i - 1].length - zeroCount;

                if (zeroCount <= j && oneCount <= k) {
                    dp[i][j][k] = Math.max(
                        dp[i][j][k],
                        1
                            + dp[i - 1][j - zeroCount]
                                [k - oneCount]);
                }
            }
        }
    }
    return dp[n][maxZeros][maxOnes];
}

const arr = [ "1", "0", "0001", "10", "111001" ];
const a = 5, b = 3;
const res = maxSubsetSize(arr, a, b);
console.log(res);

Output
4



Next Article
Article Tags :
Practice Tags :

Similar Reads