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

64 阅读3分钟

问题描述

我们需要找到一个字符串中最大的UCC子串的长度。UCC子串定义为包含至少一个'U'和至少两个连续'C'的子串。

动态规划状态定义

我们使用一个二维数组dp[i][j]来存储动态规划的状态,其中:

  • i表示字符串中的位置(从1开始,因为数组下标从0开始,所以i比实际位置多1)。
  • j表示当前考虑的子串长度。
  • dp[i][j]表示以第i个字符结尾,长度为j的子串中最大的UCC子串的长度。

初始化

在动态规划中,初始化是关键的一步,它为后续的状态转移提供了基础。

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

这段代码初始化了一个n+1m+1列的二维数组dp,并将所有值设为0。这里的n是字符串s的长度,m是子串的最大可能长度。初始化为0是因为在开始时,没有任何UCC子串,所以长度为0。

状态转移方程

状态转移是动态规划的核心,它定义了如何从一个状态转移到另一个状态。

// 填充dp数组
for (int i = 1; i <= n; i++) {
    for (int j = 1; j <= m; j++) {
        if (s.charAt(i-1) == 'C') {
            if (j >= 2) {
                dp[i][j] = Math.max(dp[i][j], dp[i-1][j-2] + 1);
            }
        } else if (s.charAt(i-1) == 'U') {
            if (j >= 1) {
                dp[i][j] = Math.max(dp[i][j], dp[i-1][j-1] + 1);
            }
        }
    }
}

这段代码遍历字符串中的每个字符,并更新dp数组。对于每个字符s.charAt(i-1)

  • 如果当前字符是'C',并且当前考虑的子串长度j至少为2,我们尝试从dp[i-1][j-2]转移过来,因为我们需要至少两个'C'来形成一个UCC子串。dp[i-1][j-2] + 1表示在之前的状态上加上当前的'C'。
  • 如果当前字符是'U',并且当前考虑的子串长度j至少为1,我们尝试从dp[i-1][j-1]转移过来,因为我们需要至少一个'U'和至少两个'C'来形成一个UCC子串。dp[i-1][j-1] + 1表示在之前的状态上加上当前的'U'。

寻找最大UCC子串长度

在填充完dp数组后,我们需要找到最大的UCC子串长度。

// 找到最大的UCC子串长度
int maxUCCLength = 0;
for (int i = 1; i <= n; i++) {
    for (int j = 1; j <= m; j++) {
        if (dp[i][j] > maxUCCLength) {
            maxUCCLength = dp[i][j];
        }
    }
}

这段代码遍历dp数组,找到最大的UCC子串长度。maxUCCLength变量用于存储当前找到的最大UCC子串长度。

返回结果

最后,solution函数返回找到的最大UCC子串长度。

return maxUCCLength;

主函数

main函数提供了一个示例字符串,并调用solution函数来计算最大UCC子串的长度。

public static void main(String[] args) {
    String s = "UCCUCCUCC";
    int m = s.length();
    System.out.println("最大UCC子串长度为: " + solution(m, s));
}

这段代码定义了一个示例字符串s,并将其长度m作为参数传递给solution函数。然后,它打印出最大UCC子串的长度。