Maximum Strings Concatenation
Last Updated :
10 Jan, 2024
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++
#include <bits/stdc++.h>
using namespace std;
int GetMax( int n, int k, vector<string>& s)
{
map< int , int > masks;
int temp = 0;
for ( auto str : s) {
temp = 0;
for ( auto ch : str) {
temp |= (1 << (ch - 'a' ));
}
masks[temp]++;
}
int ans = 0;
int tans = 0;
for ( int it = 0; it <= 1024; it++) {
if (__builtin_popcount(it) == k) {
temp = 0;
tans = 0;
for ( auto str : masks) {
if ((it & str.first) == str.first) {
temp = temp | str.first;
tans += str.second;
}
}
if (temp == it) {
ans = max(ans, tans);
}
}
}
return ans;
}
int main()
{
int n = 3;
int k = 3;
vector<string> s = { "ab" , "c" , "dfec" };
cout << GetMax(n, k, s);
return 0;
}
|
Java
import java.util.HashMap;
import java.util.Map;
import java.util.Vector;
public class Main {
static int getMax( int n, int k, Vector<String> s) {
Map<Integer, Integer> masks = new HashMap<>();
int temp = 0 ;
for (String str : s) {
temp = 0 ;
for ( char ch : str.toCharArray()) {
temp |= ( 1 << (ch - 'a' ));
}
masks.put(temp, masks.getOrDefault(temp, 0 ) + 1 );
}
int ans = 0 ;
int tans = 0 ;
for ( int it = 0 ; it <= 1024 ; it++) {
if (Integer.bitCount(it) == k) {
temp = 0 ;
tans = 0 ;
for (Map.Entry<Integer, Integer> entry : masks.entrySet()) {
int strKey = entry.getKey();
int strValue = entry.getValue();
if ((it & strKey) == strKey) {
temp |= strKey;
tans += strValue;
}
}
if (temp == it) {
ans = Math.max(ans, tans);
}
}
}
return ans;
}
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" );
System.out.println(getMax(n, k, s));
}
}
|
Python3
def get_max(n, k, s):
masks = {}
temp = 0
for string in s:
temp = 0
for char in string:
temp | = ( 1 << ( ord (char) - ord ( 'a' )))
masks[temp] = masks.get(temp, 0 ) + 1
ans = 0
tans = 0
for it in range ( 1025 ):
if bin (it).count( '1' ) = = k:
temp = 0
tans = 0
for key, value in masks.items():
if (it & key) = = key:
temp | = key
tans + = value
if temp = = it:
ans = max (ans, tans)
return ans
if __name__ = = "__main__" :
n = 3
k = 3
s = [ "ab" , "c" , "dfec" ]
print (get_max(n, k, s))
|
C#
using System;
using System.Collections.Generic;
class GFG
{
static int GetMax( int n, int k, List< string > s)
{
Dictionary< int , int > masks = new Dictionary< int , int >();
int temp = 0;
foreach ( var str in s)
{
temp = 0;
foreach ( char ch in str)
{
temp |= (1 << (ch - 'a' ));
}
if (masks.ContainsKey(temp))
masks[temp]++;
else
masks.Add(temp, 1);
}
int ans = 0;
int tans = 0;
for ( int it = 0; it <= 1024; it++)
{
if (CountSetBits(it) == k)
{
temp = 0;
tans = 0;
foreach ( var str in masks)
{
if ((it & str.Key) == str.Key)
{
temp |= str.Key;
tans += str.Value;
}
}
if (temp == it)
{
ans = Math.Max(ans, tans);
}
}
}
return ans;
}
static int CountSetBits( int n)
{
int count = 0;
while (n > 0)
{
count += n & 1;
n >>= 1;
}
return count;
}
static void Main( string [] args)
{
int n = 3;
int k = 3;
List< string > s = new List< string > { "ab" , "c" , "dfec" };
Console.WriteLine(GetMax(n, k, s));
}
}
|
Javascript
function getMax(n, k, s) {
const masks = new Map();
let temp = 0;
for (let str of s) {
temp = 0;
for (let ch of str) {
temp |= (1 << (ch.charCodeAt(0) - 'a' .charCodeAt(0)));
}
masks.set(temp, (masks.get(temp) || 0) + 1);
}
let ans = 0;
let tans = 0;
for (let it = 0; it <= 1024; it++) {
if (countSetBits(it) === k) {
temp = 0;
tans = 0;
for (let [key, value] of masks.entries()) {
if ((it & key) === key) {
temp |= key;
tans += value;
}
}
if (temp === it) {
ans = Math.max(ans, tans);
}
}
}
return ans;
}
function countSetBits(n) {
let count = 0;
while (n) {
count += n & 1;
n >>= 1;
}
return count;
}
function main() {
const n = 3;
const k = 3;
const s = [ "ab" , "c" , "dfec" ];
console.log(getMax(n, k, s));
}
main();
|
Time Complexity: O(N)
Auxiliary Space: O(N), Where N is the number of strings present in the array.
Share your thoughts in the comments
Please Login to comment...