解题思路

这是一个字符串混编问题,可以使用动态规划求解。关键点:

  1. 动态规划定义

    • 表示 的前 个字符和 的前 个字符能否混编成 的前 个字符
    • 表示使用了 的前 个字符
    • 表示使用了 的前 个字符
  2. 状态转移

    • 如果当前字符来自
    • 如果当前字符来自
  3. 基本判断

    • 长度必须匹配:
    • 初始状态:

代码

class Mixture {
public:
    bool chkMixture(string A, int n, string B, int m, string C, int v) {
        if(n + m != v) return false;
        
        vector<vector<bool>> dp(n + 1, vector<bool>(m + 1, false));
        dp[0][0] = true;
        
        // 只使用A串
        for(int i = 1; i <= n; i++) {
            dp[i][0] = dp[i-1][0] && (A[i-1] == C[i-1]);
        }
        
        // 只使用B串
        for(int j = 1; j <= m; j++) {
            dp[0][j] = dp[0][j-1] && (B[j-1] == C[j-1]);
        }
        
        // 动态规划填表
        for(int i = 1; i <= n; i++) {
            for(int j = 1; j <= m; j++) {
                // 当前字符可以来自A或B
                dp[i][j] = (dp[i-1][j] && A[i-1] == C[i+j-1]) || 
                          (dp[i][j-1] && B[j-1] == C[i+j-1]);
            }
        }
        
        return dp[n][m];
    }
};
import java.util.*;

public class Mixture {
    public boolean chkMixture(String A, int n, String B, int m, String C, int v) {
        if(n + m != v) return false;
        
        boolean[][] dp = new boolean[n + 1][m + 1];
        dp[0][0] = true;
        
        // 只使用A串
        for(int i = 1; i <= n; i++) {
            dp[i][0] = dp[i-1][0] && (A.charAt(i-1) == C.charAt(i-1));
        }
        
        // 只使用B串
        for(int j = 1; j <= m; j++) {
            dp[0][j] = dp[0][j-1] && (B.charAt(j-1) == C.charAt(j-1));
        }
        
        // 动态规划填表
        for(int i = 1; i <= n; i++) {
            for(int j = 1; j <= m; j++) {
                // 当前字符可以来自A或B
                dp[i][j] = (dp[i-1][j] && A.charAt(i-1) == C.charAt(i+j-1)) || 
                          (dp[i][j-1] && B.charAt(j-1) == C.charAt(i+j-1));
            }
        }
        
        return dp[n][m];
    }
}
# -*- coding:utf-8 -*-

class Mixture:
    def chkMixture(self, A, n, B, m, C, v):
        if n + m != v:
            return False
            
        dp = [[False] * (m + 1) for _ in range(n + 1)]
        dp[0][0] = True
        
        # Only use string A
        for i in range(1, n + 1):
            dp[i][0] = dp[i-1][0] and (A[i-1] == C[i-1])
        
        # Only use string B
        for j in range(1, m + 1):
            dp[0][j] = dp[0][j-1] and (B[j-1] == C[j-1])
        
        # Fill dp table
        for i in range(1, n + 1):
            for j in range(1, m + 1):
                # Current char can come from either A or B
                dp[i][j] = (dp[i-1][j] and A[i-1] == C[i+j-1]) or \
                          (dp[i][j-1] and B[j-1] == C[i+j-1])
        
        return dp[n][m]

算法及复杂度

  • 算法:动态规划
  • 时间复杂度:,需要填充整个
  • 空间复杂度:,需要二维 数组