黑产行为序列识别 | 豆包MarsCode AI刷题

42 阅读2分钟

解题思路

  1. 理解问题

    • 我们需要在字符串 S 中找到所有可能的子序列 P 的出现次数。
    • 子序列 P 中的字符在 S 中可以不连续,但顺序必须一致。
  2. 数据结构选择

    • 由于我们需要动态地计算子序列的出现次数,可以使用动态规划(DP)来解决这个问题。
  3. 算法步骤

    • 创建一个二维数组 dp,其中 dp[i][j] 表示 S 的前 i 个字符中子序列 P 的前 j 个字符的出现次数。

    • 初始化 dp[0][0] = 1,表示空字符串到空字符串的匹配次数为1。

    • 遍历字符串 S 的每个字符,并更新 dp 数组:

      • 如果 S[i-1] == P[j-1],则 dp[i][j] = dp[i-1][j-1] + dp[i-1][j]
      • 否则,dp[i][j] = dp[i-1][j]
    • 最终,dp[S.length()][P.length()] 就是 S 中子序列 P 的出现次数。

  4. 取模操作

    • 由于结果需要对 10^9 + 7 取模,我们在每次更新 dp 数组时都要进行取模操作。
public class Main {
    public static int solution(String S, String P) {
        int mod = 1000000007;
        int n = S.length();
        int m = P.length();
        
        // dp[i][j] 表示 S 的前 i 个字符中子序列 P 的前 j 个字符的出现次数
        int[][] dp = new int[n + 1][m + 1];
        
        // 初始化:空字符串到空字符串的匹配次数为1
        dp[0][0] = 1;
        
        // 遍历 S 的每个字符
        for (int i = 1; i <= n; i++) {
            // 对于每个字符,初始化 dp[i][0] 为1,因为空字符串是任何字符串的子序列
            dp[i][0] = 1;
            for (int j = 1; j <= m; j++) {
                // 如果 S[i-1] 和 P[j-1] 匹配
                if (S.charAt(i - 1) == P.charAt(j - 1)) {
                    dp[i][j] = (dp[i - 1][j - 1] + dp[i - 1][j]) % mod;
                } else {
                    // 如果不匹配,则继承前一个状态
                    dp[i][j] = dp[i - 1][j];
                }
            }
        }
        
        // 返回 S 中子序列 P 的出现次数
        return dp[n][m];
    }

    public static void main(String[] args) {
        System.out.println(solution("ABC", "A") == 1);
        System.out.println(solution("AABCCD", "CCD") == 1);
        System.out.println(solution("AABCCD", "C") == 2);
    }
}

代码解释

  1. 初始化

    • dp[0][0] = 1:空字符串到空字符串的匹配次数为1。
    • dp[i][0] = 1:任何字符串的前 i 个字符中,空字符串的出现次数为1。
  2. 动态规划更新

    • 对于每个字符 S[i-1],我们检查它是否与 P[j-1] 匹配。
    • 如果匹配,dp[i][j] 更新为 dp[i-1][j-1] + dp[i-1][j],表示当前字符匹配的情况下,加上不匹配的情况。
    • 如果不匹配,dp[i][j] 继承前一个状态 dp[i-1][j]
  3. 取模操作

    • 在每次更新 dp 数组时,都对结果取模 10^9 + 7,以防止溢出。
  4. 返回结果

    • 最终,dp[n][m] 就是 S 中子序列 P 的出现次数。