Horje
Maximum Strings Concatenation

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.




Reffered: https://www.geeksforgeeks.org


Bit Magic

Related
XOR Graph Minimum Spanning Tree XOR Graph Minimum Spanning Tree
Find the value of X and Y such that X Bitwise XOR Y equals to (X+Y)/2 Find the value of X and Y such that X Bitwise XOR Y equals to (X+Y)/2
XOR of Bitwise OR Pairs from Two Arrays XOR of Bitwise OR Pairs from Two Arrays
Find two numbers whose difference is given as Binary string Find two numbers whose difference is given as Binary string
Non-Repeating Bitwise OR Permutation Non-Repeating Bitwise OR Permutation

Type:
Geek
Category:
Coding
Sub Category:
Tutorial
Uploaded by:
Admin
Views:
13