牛客题解 | 字符混编

题目

题目链接

解题思路

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

  1. 动态规划定义

    • \(dp[i][j]\) 表示 \(A\) 的前 \(i\) 个字符和 \(B\) 的前 \(j\) 个字符能否混编成 \(C\) 的前 \(i+j\) 个字符
    • \(i\) 表示使用了 \(A\) 的前 \(i\) 个字符
    • \(j\) 表示使用了 \(B\) 的前 \(j\) 个字符
  2. 状态转移

    • 如果当前字符来自 \(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]\)
  3. 基本判断

    • 长度必须匹配:\(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或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]

算法及复杂度

  • 算法:动态规划
  • 时间复杂度:\(\mathcal{O}(nm)\),需要填充整个 \(dp\)
  • 空间复杂度:\(\mathcal{O}(nm)\),需要二维 \(dp\) 数组
posted @ 2025-03-04 12:09  wangxiaoxiao  阅读(4)  评论(0)    收藏  举报