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

46 阅读2分钟

image.png

SOLUTION: DP

  • dp[i][j] = number of ways to build the first i characters of target using the first j columns (0 to j-1) of words
  • There are two choices when filling dp[i][j]:
    • 1.Do not use column j-1 at all: Just inherit the value from dp[i][j-1].
    • 2.Use column j-1 to build target[i-1]:For that, we find how many times target[i-1] appears in column j-1 of any word — let’s call this count(target[i-1],j-1).
  • dp[i][j] = dp[i][j-1] + dp[i-1][j-1] * count(j-1, target[i-1])
class Solution {
    public int numWays(String[] words, String target) {
        
        int arrSize = words.length;
        int wordLen = words[0].length();
        int targetLen = target.length();
        // dp[i][j] = number of ways to build the first i characters of `target` 
        // using the first j columns (0 to j-1) of `words`
        int[][] dp = new int[targetLen][wordLen];

        // count[char][i] how many times a char c appears in column i of any word
        int[][] count = new int[26][wordLen];

        for (int i = 0; i < wordLen; i++) {
            for (int j = 0; j < arrSize; j++) {
                char c = words[j].charAt(i);
                count[c - 'a'][i]++;
            }
        }

        // ways to build first character of target using only column 0
        dp[0][0] = count[target.charAt(0) - 'a'][0];

        // constructing first character of target using columns 0 to wordLen
        for (int i = 1; i < wordLen; i++) {
            dp[0][i] = dp[0][i - 1] + count[target.charAt(0) - 'a'][i];
        }

        for (int i = 1; i < targetLen; i++) {
            for (int j = i; j < wordLen; j++) { // j=i, because cant visit back k
                char targetChar = target.charAt(i);
                dp[i][j] = dp[i][j - 1] + dp[i - 1][j - 1] * count[targetChar - 'a'][j] ;
            }
        }

        return dp[targetLen - 1][wordLen - 1];

    }
}

// dp[i][j] = number of ways to build the first i characters of `target` using the first j columns (0 to j-1) of `words`
// There are two choices when filling dp[i][j]:
//     1.Do not use column j-1 at all: Just inherit the value from dp[i][j-1].
//     2.Use column j-1 to build target[i-1]:For that, we find how many times target[i-1] appears in column j-1 of any word — let’s call this count(target[i-1],j-1).
// dp[i][j] = dp[i][j-1] + dp[i-1][j-1] * count(j-1, target[i-1])

If uoverflow, use res % MOD

class Solution {
    public int numWays(String[] words, String target) {
        
        int arrSize = words.length;
        int wordLen = words[0].length();
        int targetLen = target.length();
        long mod = 1_000_000_007;
        // dp[i][j] = number of ways to build the first i characters of `target` 
        // using the first j columns (0 to j-1) of `words`
        long[][] dp = new long[targetLen][wordLen];

        // count[char][i] how many times a char c appears in column i of any word
        long[][] count = new long[26][wordLen];

        for (int i = 0; i < wordLen; i++) {
            for (int j = 0; j < arrSize; j++) {
                char c = words[j].charAt(i);
                count[c - 'a'][i]++;
            }
        }

        // ways to build first character of target using only column 0
        dp[0][0] = count[target.charAt(0) - 'a'][0];

        // constructing first character of target using columns 0 to wordLen
        for (int i = 1; i < wordLen; i++) {
            dp[0][i] = (dp[0][i - 1] + count[target.charAt(0) - 'a'][i]) % mod;
        }

        for (int i = 1; i < targetLen; i++) {
            for (int j = i; j < wordLen; j++) { // j=i, because cant visit back k
                char targetChar = target.charAt(i);
                dp[i][j] =( dp[i][j - 1] + dp[i - 1][j - 1] * count[targetChar - 'a'][j]) % mod ;
            }
        }

        return (int) dp[targetLen - 1][wordLen - 1];

    }
}