Program to find number of ways to form a target string given a dictionary in Python

PythonServer Side Programming

Suppose we have a list of string called words, where all elements are of same length. We also have a string called target. We have to generate target using the given words under the following rules −

  • We should generate target from left to right.

  • To get the ith character (0-indexed) of target, we can select the kth character of the jth string in words when target[i] is same as words[j][k].

  • Once we use the kth character of the jth string of words, we cannot use the xth character of any string in words where x <= k.

  • Repeat these process until we form the entire target string.

So we have to find the number of ways to get target from words. The answer may be very large, so return answer modulo 10^9 + 7.

So, if the input is like words = ["pqqp","qppq"], target = "qpq", then the output will be 4 because

  • "qpq" -> at index 0 ("qppq"), at index 1 ("qppq"), at index 2 ("pqqp")

  • "qpq" -> at index 0 ("qppq"), at index 1 ("qppq"), at index 3 ("qppq")

  • "qpq" -> at index 0 ("qppq"), at index 2 ("qppq"), at index 3 ("qppq")

  • "qpq" -> at index 1 ("pqqp"), at index 2 ("qppq"), at index 3 ("qppq")

To solve this, we will follow these steps −

  • m := number of words,

  • n := size of target

  • d := a list of size m, filled with m different empty maps

  • for each w in words, do

    • for each index j and word c in w, do

      • d[j, c] := d[j, c] + 1

  • Define a function dfs() . This will take i, j

  • if i is same as n, then

    • return 1

  • if i is same as m, then

    • return 0

  • return (dfs(i, j+1) + dfs(i+1, j+1) * d[j, target[i]]) mod (10^9 + 7)

  • From the main method return dfs(0, 0)


Let us see the following implementation to get better understanding

from collections import Counter
def solve(words, target):
   m, n = len(words[0]), len(target)
   d = [Counter() for _ in range(m)]
   for w in words:
      for j, c in enumerate(w):
         d[j][c] += 1

   def dfs(i, j):
      if i == n:
         return 1
      if j == m:
         return 0
      return (dfs(i, j+1) + dfs(i+1, j+1) * d[j][target[i]]) % int(1e9 + 7)

   return dfs(0, 0)

words = ["pqqp","qppq"]
target = "qpq"
print(solve(words, target))


"95643", "45963"


Published on 07-Oct-2021 07:23:09