题目
题目链接
解题思路
这是一个字符串混编问题,可以使用动态规划求解。关键点:
-
动态规划定义:
- \(dp[i][j]\) 表示 \(A\) 的前 \(i\) 个字符和 \(B\) 的前 \(j\) 个字符能否混编成 \(C\) 的前 \(i+j\) 个字符
- \(i\) 表示使用了 \(A\) 的前 \(i\) 个字符
- \(j\) 表示使用了 \(B\) 的前 \(j\) 个字符
-
状态转移:
- 如果当前字符来自 \(A\):\(dp[i][j] = dp[i-1][j] \land A[i-1] = C[i+j-1]\)
- 如果当前字符来自 \(B\):\(dp[i][j] = dp[i][j-1] \land B[j-1] = C[i+j-1]\)
-
基本判断:
- 长度必须匹配:\(n + m = v\)
- 初始状态:\(dp[0][0] = true\)
代码
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或Bdp[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或Bdp[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 Falsedp = [[False] * (m + 1) for _ in range(n + 1)]dp[0][0] = True# Only use string Afor i in range(1, n + 1):dp[i][0] = dp[i-1][0] and (A[i-1] == C[i-1])# Only use string Bfor j in range(1, m + 1):dp[0][j] = dp[0][j-1] and (B[j-1] == C[j-1])# Fill dp tablefor i in range(1, n + 1):for j in range(1, m + 1):# Current char can come from either A or Bdp[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]
算法及复杂度
- 算法:动态规划
- 时间复杂度:\(\mathcal{O}(nm)\),需要填充整个 \(dp\) 表
- 空间复杂度:\(\mathcal{O}(nm)\),需要二维 \(dp\) 数组