Description
You are given an array of strings arr. A string s is formed by the concatenation of a subsequence of arr that has unique characters.
Return the maximum possible length of s.
A subsequence is an array that can be derived from another array by deleting some or no elements without changing the order of the remaining elements.
Example 1:
Input: arr = ["un","iq","ue"]
Output: 4
Explanation: All the valid concatenations are:
- ""
- "un"
- "iq"
- "ue"
- "uniq" ("un" + "iq")
- "ique" ("iq" + "ue")
Maximum length is 4.
Example 2:
Input: arr = ["cha","r","act","ers"]
Output: 6
Explanation: Possible longest valid concatenations are "chaers" ("cha" + "ers") and "acters" ("act" + "ers").
Example 3:
Input: arr = ["abcdefghijklmnopqrstuvwxyz"]
Output: 26
Explanation: The only string in arr has all 26 characters.
Constraints:
1 <= arr.length <= 16
1 <= arr[i].length <= 26
arr[i] contains only lowercase English letters.
Solution
Recursive
Recursive, for each string, use it or don't use it. We could only use it when the characters don't appear before.
Time complexity: o ( 2 n ) o(2^n) o(2n)
Space complexity: o ( n ) o(n) o(n)
DP
Use set
in dp, every time check if current string could be added to the set.
Code
Recursive
python3
class Solution:
def maxLength(self, arr: List[str]) -> int:
visited_char = {}
def helper(index: int) -> int:
if index >= len(arr):
return 0
res = 0
could_use = True
for each_c in arr[index]:
if visited_char.get(each_c, 0) > 0:
could_use = False
visited_char[each_c] = visited_char.get(each_c, 0) + 1
if could_use:
res = max(res, len(arr[index]) + helper(index + 1))
# remove from visited_set, don't use
for each_c in arr[index]:
visited_char[each_c] -= 1
res = max(res, helper(index + 1))
return res
return helper(0)
DP
python3
class Solution:
def maxLength(self, arr: List[str]) -> int:
dp = [set()]
for each_string in arr:
string_set = set(each_string)
if len(string_set) < len(each_string):
continue
prev_dp = dp[:]
for prev_set in prev_dp:
if string_set & prev_set:
continue
else:
dp.append(string_set | prev_set)
return max(len(each_set) for each_set in dp)