最大UCC子串计算 | 豆包MarsCode AI刷题

66 阅读3分钟

代码展示:public class Main { public static int solution(int m, String s) { int n = s.length(); int[][] dp = new int[n + 1][m + 1];

    初始化 dp 数组
    for (int i = 0; i <= n; i++) {
        for (int j = 0; j <= m; j++) {
            dp[i][j] = 0;
        }
    }

     状态转移
    for (int i = 1; i <= n; i++) {
        for (int j = 0; j <= m; j++) {
            // 考虑当前字符为 'U' 或 'C' 的情况
            if (s.charAt(i - 1) == 'U') {
                // 尝试在后面插入 "CC"
                if (j >= 2) {
                    dp[i][j] = Math.max(dp[i][j], dp[i - 1][j - 2] + 1);
                }
            } else if (s.charAt(i - 1) == 'C') {
                // 尝试在前面插入 'U' 和在后面插入 'C'
                if (j >= 2) {
                    dp[i][j] = Math.max(dp[i][j], dp[i - 1][j - 2] + 1);
                }
                // 尝试在前面插入 "UC"
                if (j >= 2) {
                    dp[i][j] = Math.max(dp[i][j], dp[i - 1][j - 2] + 1);
                }

                if (s.charAt(i - 3) == 'U' && s.charAt(i - 2) == 'C' && s.charAt(i - 1) == 'C') {
                    // 不需要再插入 'C',直接继承前面的状态
                    dp[i][j] = Math.max(dp[i][j], dp[i - 3][j] + 1);
                }
            }

            // 考虑删除或替换操作
            dp[i][j] = Math.max(dp[i][j], dp[i - 1][j]);
        }
    }

    // 计算最终结果
    int maxCount = 0;
    for (int j = 0; j <= m; j++) {
        maxCount = Math.max(maxCount, dp[n][j] + (m - j) / 3);
    }
    return maxCount;
}

public static void main(String[] args) {
    System.out.println(solution(3, "UCUUCCCCC") == 3);
    System.out.println(solution(6, "U") == 2);
    System.out.println(solution(2, "UCCUUU") == 2);
    System.out.println(solution(10, "CCU") == 4);
    System.out.println(solution(7, "CCUUUCUCU") == 5);
}

} 题目描述

小S有一个由字符 'U' 和 'C' 组成的字符串 S,并希望在编辑距离不超过给定值 m 的条件下,尽可能多地在字符串中找到 "UCC" 子串。编辑距离定义为将字符串 S 转化为其他字符串时所需的最少编辑操作次数。允许的每次编辑操作是插入、删除或替换单个字符。

解题思路

  1. 理解问题:

    • 我们需要在字符串 S 中找到尽可能多的 "UCC" 子串。
    • 编辑距离限制 m 表示我们可以进行最多 m 次编辑操作(插入、删除、替换)。
  2. 动态规划:

    • 使用动态规划来解决这个问题。定义一个二维数组 dp[i][j],表示在字符串 S 的前 i 个字符中,使用最多 j 次编辑操作,最多能找到多少个 "UCC" 子串。
  3. 状态转移:

    • 对于每个字符 S[i],我们可以考虑以下几种情况:

      • 如果 S[i] 是 'U',我们可以尝试在后面插入 "CC"
      • 如果 S[i] 是 'C',我们可以尝试在前面插入 'U' 或在后面插入 'C'
      • 如果 S[i−2] 和 S[i−1] 是 "UC",我们可以尝试在后面插入 'C'

知识总结

新知识点

  1. 动态规划:

    • 动态规划是一种通过将问题分解为子问题并存储子问题的解来解决复杂问题的方法。在本题中,我们使用动态规划来计算在不同编辑操作次数下,最多能找到多少个 "UCC" 子串。
  2. 编辑距离:

    • 编辑距离是指将一个字符串转换为另一个字符串所需的最少编辑操作次数。在本题中,编辑操作包括插入、删除和替换。
  3. 状态转移方程

    • 状态转移方程是动态规划中的关键部分,它描述了如何从子问题的解推导出原问题的解。在本题中,我们通过考虑不同的编辑操作来推导出状态转移方程。

学习建议

  1. 理解动态规划

    • 动态规划是解决复杂问题的强大工具,但理解其背后的原理和状态转移方程是关键。建议通过练习更多的动态规划题目来加深理解。

      1. 掌握编辑距离
    • 编辑距离是字符串处理中的一个重要概念,掌握其计算方法和应用场景有助于解决类似的问题。