diff --git a/cs/number-of-ways-to-form-a-target-string-given-a-dictionary.cs b/cs/number-of-ways-to-form-a-target-string-given-a-dictionary.cs new file mode 100644 index 0000000..7688602 --- /dev/null +++ b/cs/number-of-ways-to-form-a-target-string-given-a-dictionary.cs @@ -0,0 +1,56 @@ +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; + } +}