深度优先搜索 + 位运算
需要注意的是,如何去判断当前字符串是否与已经组合的字符串是否有重复。
可以使用位掩码来解决。
数字与字母映射(‘a’ -> 1, ‘b’ -> 2, ‘c’ -> 4)以此类推,如果已组合的字符位掩码与当前所选择的子字符的位掩码进行与运算后,得到的结果为0,说明无重复。
class Solution {
public int maxLength(List<String> arr) {
if (arr.size() == 0) return 0;
return dfs(arr, 0, 0);
}
private int dfs(List<String> arr, int start, int bitMask) {
if (start == arr.size())
return 0;
int ans = 0;
for (int i = start; i < arr.size(); i ++) {
// 计算当前需要级联字符串的位掩码
int bit = getBitMask(arr.get(i));
// 如果当前字符串的位掩码为0,说明当前字符串中存在重复字符
// 如果当前字符串位掩码与之前已经级联的字符串位掩码相与不为0则说明
// 当前字符串与之前字符串存在相同字符
if (bit == 0 || (bitMask & bit) != 0) continue;
ans = Math.max(ans, dfs(arr, i + 1, bitMask | bit) + arr.get(i).length());
}
return ans;
}
/**
* 获取字符串的位掩码,比如“ab” 掩码为11
* “aa” 为0 , 掩码为0 说明字符串有重复字符
*/
private int getBitMask(String s) {
int bitMask = 0;
for (char c : s.toCharArray()) {
int bit = 1 << (c - 'a');
// 字符串有重复字符,如 aba、aa、cc
if ((bitMask & bit) != 0) return 0;
bitMask |= bit;
}
return bitMask;
}
}