Scribbling

LeetCode: 1639. Number of Ways to Form a Target String Given a Dictionary 본문

Computer Science/Algorithms & Data Structures

LeetCode: 1639. Number of Ways to Form a Target String Given a Dictionary

focalpoint 2023. 4. 7. 00:23

 

A dynamic programming approach:

 

Let dp[i, j] be the total number of cases of target[i] corresponding to jth position

dp[i, j] = dp[i][j-1] + dp[i-1][j-1] * counter[j, target[i]]

 

1) Bottom-up

import string
from functools import lru_cache
class Solution:
    def numWays(self, words: List[str], target: str) -> int:
        
        N = len(words[0])
        freqs = [{c: 0 for c in string.ascii_lowercase} for _ in range(N)]
        
        for word in words:
            for i, c in enumerate(word):
                freqs[i][c] += 1

        m = len(target)
        n = len(words[0])
        dp = [[0] * n for _ in range(m)]

        dp[0][0] = freqs[0][target[0]]
        for i in range(1, n):
            dp[0][i] = dp[0][i-1] + freqs[i][target[0]]

        for i in range(1, m):
            for j in range(1, n):
                dp[i][j] = dp[i][j-1] + dp[i-1][j-1] * freqs[j][target[i]]
        return dp[-1][-1] % (10**9+7)

 

2) Top-down

import string
from functools import lru_cache
class Solution:
    def numWays(self, words: List[str], target: str) -> int:
        
        N = len(words[0])
        freqs = [{c: 0 for c in string.ascii_lowercase} for _ in range(N)]
        
        for word in words:
            for i, c in enumerate(word):
                freqs[i][c] += 1

        m = len(target)
        n = len(words[0])
        dp = [[0] * n for _ in range(m)]

        @lru_cache(None)
        def dfs(i, j):
            nonlocal N, target
            if i == len(target):
                return 1
            if j == N:
                return 0

            return (freqs[j][target[i]] * dfs(i+1, j+1) + dfs(i, j+1)) % (10**9+7)

        return dfs(0, 0)