public class Solution { private static readonly int MOD = 1000000007; private static int[,] GetFreqs(string[] words) { var freqs = new int[words[0].Length, 26]; foreach (var word in words) { for (int i = 0; i < word.Length; ++i) { ++freqs[i, word[i] - 'a']; } } return freqs; } private struct Counter { public long Previous; public long Current; } private static void PushCurrent(Counter[] counters) { for (var i = 0; i < counters.Length; ++i) { counters[i].Current = counters[i].Previous; } } private static void PopCurrent(Counter[] counters) { for (var i = 0; i < counters.Length; ++i) { counters[i].Previous = counters[i].Current; } } public int NumWays(string[] words, string target) { var freqs = GetFreqs(words); var counters = new Counter[target.Length + 1]; counters[0].Previous = 1; for (var length = 1; length <= words[0].Length; ++length) { PushCurrent(counters); for (var j = 1; j <= target.Length; ++j) { var pos = target[j - 1] - 'a'; counters[j].Current += freqs[length - 1, pos] * counters[j - 1].Previous % MOD; counters[j].Current %= MOD; } PopCurrent(counters); } return (int)counters[target.Length].Previous; } }