My first instinct was greedy and it was wrong.
Model each word as a 26-bit mask of its characters, filtering out any word with internal duplicates. Then use dynamic programming over subsets of characters (or DFS with memoization) to find the maximum total length of concatenated words whose masks are pairwise disjoint. The DP state is the current character mask, and transitions add a word if its mask doesn't overlap.
Pro tip: Mention that the DP over character masks is feasible because there are only 2^26 possible masks, but in practice you can use a hash map to store only reachable states, and you can also prune by sorting words by length descending to find good solutions early. Also, note that the problem is essentially maximum weight independent set on a conflict graph, but the bitmask DP is more efficient here.
For each word, compute a 26-bit integer where each bit represents a letter. If a word has any duplicate character, discard it immediately.
Let dp[mask] be the maximum total length achievable using a set of words whose combined character mask is exactly mask. Initialize dp[0] = 0. For each word mask w, update dp[mask | w] = max(dp[mask | w], dp[mask] + len(word)) if (mask & w) == 0.
Iterate over all masks from 0 to (1<<26)-1, but only process masks that are reachable (dp[mask] > 0). Alternatively, use a hash map to store only reachable states to save memory and time.
Keep a variable max_len updated whenever dp[mask] is updated. After processing all words, return max_len.
Time complexity is O(N * 2^26) in the worst case, but with reachable states it's much less. Space is O(2^26) for the DP array, which can be reduced using a hash map. Mention that for large N, this is still efficient because 2^26 is about 67 million, which is borderline but manageable with optimizations.
AI-generated suggestions, not part of the candidate's original notes. May be inaccurate — verify before relying on them.