Open In App

Maximum Strings Concatenation

Last Updated : 10 Jan, 2024
Improve
Improve
Like Article
Like
Save
Share
Report

Given an array of strings, where each string consists of lowercase characters from a to j. You need to find the maximum number of strings that can be concatenated together such that the resulting string can be made out of exactly k distinct characters.

Example:

Input: n = 4, str = [ “abc”, “de”, “fg”, “h”], k = 5
Output: 3
Explanation: The strings de, fg and h would add up to defgh which has exactly 5 distinct characters.

Input: n = 3, str = [ “abcde”, “de”, “fghi”], k = 5
Output: 2
Explanation: The strings “abcde” and “de” would add up to abcdede which has exactly 5 distinct characters.

Approach: This can be solved with the following idea:

The main idea is to use a bitmask approach. We’ll represent each string as a bitmask where each bit corresponds to a character in the alphabet (a to j). If a bit is set, it means the corresponding character is present in the string. By manipulating these bitmasks and using bitwise operations, we can efficiently check if a set of strings can be concatenated to form a string with exactly k distinct characters.

Below are the steps involved:

  • Create a map called masks to store bitmasks of all input strings.
  • Iterate through each string in the input s and convert it into a bitmask. Set bits in the bitmask based on the characters present in the string.
  • Initialize ans to 0. This variable will keep track of the maximum number of concatenated strings that satisfy the condition.
  • Iterate through numbers from 0 to 1024 (2^10), representing possible combinations of characters (bitmasks) with up to 10 distinct characters (as there are 10 possible characters from ‘a’ to ‘j’).
    • For each number in the iteration, check if it has exactly k set bits using the __builtin_popcount function. If it doesn’t, move to the next number.
    • Initialize temp and tans to 0. The temp will be used to combine bitmasks of strings, and tans will store the count of concatenated strings for the current bitmask.
    • Iterate through the masks map and check if the current bitmask includes the bitmask of a string. If it does, set the corresponding bits in temp and add the count of that string to tans.
    • Check if temp is equal to the current bitmask. If they match, it means that all required characters are present in the concatenated strings.
    • Update ans with the maximum of its current value and tans if the bitmasks match.
  • Return the final value of ans, which represents the maximum number of concatenated strings with exactly k distinct characters.

Below is the implementation of the code:

C++




// C++ Implementation
#include <bits/stdc++.h>
using namespace std;
 
// Function to find minimum number of string to comcat
int GetMax(int n, int k, vector<string>& s)
{
 
    // Initialze a map
    map<int, int> masks;
    int temp = 0;
 
    // Iterate in vector s
    for (auto str : s) {
        temp = 0;
 
        // Do OR of each character
        for (auto ch : str) {
 
            temp |= (1 << (ch - 'a'));
        }
        masks[temp]++;
    }
 
    // Iterate for 1024 as the bits
    int ans = 0;
    int tans = 0;
    for (int it = 0; it <= 1024; it++) {
 
        // Count of set bits in it
        if (__builtin_popcount(it) == k) {
            temp = 0;
            tans = 0;
 
            // Iterate in mask map
            for (auto str : masks) {
                if ((it & str.first) == str.first) {
                    temp = temp | str.first;
                    tans += str.second;
                }
            }
 
            // Update the max
            if (temp == it) {
                ans = max(ans, tans);
            }
        }
    }
 
    // Return the maximum value
    return ans;
}
 
// Driver code
int main()
{
 
    int n = 3;
    int k = 3;
    vector<string> s = { "ab", "c", "dfec" };
 
    // Function call
    cout << GetMax(n, k, s);
    return 0;
}


Java




import java.util.HashMap;
import java.util.Map;
import java.util.Vector;
 
public class Main {
    // Function to find the minimum number of strings to concatenate
    static int getMax(int n, int k, Vector<String> s) {
 
        // Initialize a map
        Map<Integer, Integer> masks = new HashMap<>();
        int temp = 0;
 
        // Iterate in the vector s
        for (String str : s) {
            temp = 0;
 
            // Do OR of each character
            for (char ch : str.toCharArray()) {
                temp |= (1 << (ch - 'a'));
            }
            masks.put(temp, masks.getOrDefault(temp, 0) + 1);
        }
 
        // Iterate for 1024 as the bits
        int ans = 0;
        int tans = 0;
        for (int it = 0; it <= 1024; it++) {
 
            // Count of set bits in it
            if (Integer.bitCount(it) == k) {
                temp = 0;
                tans = 0;
 
                // Iterate in mask map
                for (Map.Entry<Integer, Integer> entry : masks.entrySet()) {
                    int strKey = entry.getKey();
                    int strValue = entry.getValue();
 
                    if ((it & strKey) == strKey) {
                        temp |= strKey;
                        tans += strValue;
                    }
                }
 
                // Update the max
                if (temp == it) {
                    ans = Math.max(ans, tans);
                }
            }
        }
 
        // Return the maximum value
        return ans;
    }
 
    // Driver code
    public static void main(String[] args) {
        int n = 3;
        int k = 3;
        Vector<String> s = new Vector<>();
        s.add("ab");
        s.add("c");
        s.add("dfec");
 
        // Function call
        System.out.println(getMax(n, k, s));
    }
}
 
 
// This code is contributed by rambabuguphka


Python3




def get_max(n, k, s):
    # Initialize a dictionary
    masks = {}
    temp = 0
 
    # Iterate in list s
    for string in s:
        temp = 0
 
        # Do OR of each character
        for char in string:
            temp |= (1 << (ord(char) - ord('a')))
        masks[temp] = masks.get(temp, 0) + 1
 
    # Iterate for 1024 as the bits
    ans = 0
    tans = 0
    for it in range(1025):
 
        # Count of set bits in it
        if bin(it).count('1') == k:
            temp = 0
            tans = 0
 
            # Iterate in mask dictionary
            for key, value in masks.items():
                if (it & key) == key:
                    temp |= key
                    tans += value
 
            # Update the max
            if temp == it:
                ans = max(ans, tans)
 
    # Return the maximum value
    return ans
 
# Driver code
if __name__ == "__main__":
    n = 3
    k = 3
    s = ["ab", "c", "dfec"]
 
    # Function call
    print(get_max(n, k, s))


C#




// C# Implementation
using System;
using System.Collections.Generic;
 
class GFG
{
    // Function to find minimum number of strings to concatenate
    static int GetMax(int n, int k, List<string> s)
    {
        // Initialize a dictionary
        Dictionary<int, int> masks = new Dictionary<int, int>();
        int temp = 0;
 
        // Iterate in list s
        foreach (var str in s)
        {
            temp = 0;
 
            // Do OR of each character
            foreach (char ch in str)
            {
                temp |= (1 << (ch - 'a'));
            }
            if (masks.ContainsKey(temp))
                masks[temp]++;
            else
                masks.Add(temp, 1);
        }
 
        // Iterate for 1024 as the bits
        int ans = 0;
        int tans = 0;
        for (int it = 0; it <= 1024; it++)
        {
            // Count of set bits in it
            if (CountSetBits(it) == k)
            {
                temp = 0;
                tans = 0;
 
                // Iterate in mask map
                foreach (var str in masks)
                {
                    if ((it & str.Key) == str.Key)
                    {
                        temp |= str.Key;
                        tans += str.Value;
                    }
                }
 
                // Update the max
                if (temp == it)
                {
                    ans = Math.Max(ans, tans);
                }
            }
        }
 
        // Return the maximum value
        return ans;
    }
 
    // Function to count set bits
    static int CountSetBits(int n)
    {
        int count = 0;
        while (n > 0)
        {
            count += n & 1;
            n >>= 1;
        }
        return count;
    }
 
    // Driver code
    static void Main(string[] args)
    {
        int n = 3;
        int k = 3;
        List<string> s = new List<string> { "ab", "c", "dfec" };
 
        // Function call
        Console.WriteLine(GetMax(n, k, s));
    }
}


Javascript




// Function to find minimum number of strings to concatenate
function getMax(n, k, s) {
    // Initialize a map
    const masks = new Map();
    let temp = 0;
 
    // Iterate over each string in array s
    for (let str of s) {
        temp = 0;
 
        // Perform bitwise OR of each character
        for (let ch of str) {
            temp |= (1 << (ch.charCodeAt(0) - 'a'.charCodeAt(0)));
        }
        masks.set(temp, (masks.get(temp) || 0) + 1);
    }
 
    // Initialize variables for the maximum value
    let ans = 0;
    let tans = 0;
 
    // Iterate up to 1024 as the bits
    for (let it = 0; it <= 1024; it++) {
 
        // Count the set bits in it
        if (countSetBits(it) === k) {
            temp = 0;
            tans = 0;
 
            // Iterate over the mask map
            for (let [key, value] of masks.entries()) {
                if ((it & key) === key) {
                    temp |= key;
                    tans += value;
                }
            }
 
            // Update the maximum value
            if (temp === it) {
                ans = Math.max(ans, tans);
            }
        }
    }
 
    // Return the maximum value
    return ans;
}
 
// Function to count the set bits
function countSetBits(n) {
    let count = 0;
    while (n) {
        count += n & 1;
        n >>= 1;
    }
    return count;
}
 
// Driver code
function main() {
    const n = 3;
    const k = 3;
    const s = ["ab", "c", "dfec"];
 
    // Function call
    console.log(getMax(n, k, s));
}
 
// Invoke the main function
main();
 
// This code is contributed by shivamgupta310570


Output

2

Time Complexity: O(N)
Auxiliary Space: O(N), Where N is the number of strings present in the array.



Like Article
Suggest improvement
Share your thoughts in the comments

Similar Reads