1239.Maximum Length of a Concatenated String with Unique Characters

1239.Maximum Length of a Concatenated String with Unique Characters

Description:

Given an array of strings arr. String s is a concatenation of a sub-sequence of arr which have unique characters.

Return the maximum possible length of s.

Sample Input:

1
2
3
4
Input: arr = ["un","iq","ue"]
Output: 4
Explanation: All possible concatenations are "","un","iq","ue","uniq" and "ique".
Maximum length is 4.
1
2
Input: arr = ["abcdefghijklmnopqrstuvwxyz"]
Output: 26

Constraints:

  • 1 <= arr.length <= 16
  • 1 <= arr[i].length <= 26
  • arr[i] contains only lower case English letters.

Note:

  • A subsequence should preserve the order.

    • For example, arr = [“un”,”iq”,”ue”], “iqun” is not a valid answer.
    • Corollary:
      • However, we only want the length of the string, so the order of the strings are trivial.
  • The constraints has implied us that the algorithm could be exponential.

  • if arr[i] itself contains duplicate characters, it’s invalid.

BruteForce:

Traverse all the string pair, find if the concantenated string has duplicate char.

Time Complexity $O(2^n)$ : each string can be cancatenated or not.

Technique:

Since the arr[i].length<=26<32, we can use a 32bit int to do the char count

(How many times each character present in a string instead of map)

Time Complexity $O(2^n)$ : each string can be cancatenated or not.

Space Complexity $O(n)$ : using DFS recursion, the space complexity equals to the depth of recursion.

Sample:

image-20210922201019533

Referenced from Hua Hua@Youtube

Code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
#include <string.h>
#include <iostream>
#include <algorithm>
#include <vector>
#include <unordered_map>
using namespace std;
class Solution
{
public:
/*
Input: arr = ["un","iq","ue"]
Output: 4
Explanation: All possible concatenations are "","un","iq","ue","uniq" and "ique".
Maximum length is 4.
*/
int maxLength(vector<string> &arr)
{
//valid string
vector<int> a;
for (const string &x : arr)
{
//bit representations
int mask = 0;
for (const auto ch : x)
{
//bit representation
mask |= 1 << (ch - 'a');
}

//if the char used != the length of string, it contains duplicates.
//ignore the string
if (__builtin_popcount(mask) != x.length())
continue;

a.push_back(mask);
}

//s is the index of string, mask is the present state
int ans = 0;
function<void(int, int)> dfs = [&](int s, int mask)
{
//update the result
ans = max(ans, __builtin_popcount(mask));
for (int i = s; i < a.size(); i++)
{
//if the result is valid
if (__builtin_popcount(mask & a[i]) == 0)
//go to combine with next element
dfs(i + 1, mask | a[i]);
}
};

dfs(0, 0);
return ans;
}
};