以《小R的字符串生成方式》为例,解析AI刷题功能亮点 | 豆包MarsCode AI刷题

111 阅读4分钟

本次我将以《小R的字符串生成方式》这道题为例,通过这篇文章来解析豆包MarsCode AI刷题的亮点所在;

题面如下:

image.png

问题理解

题目要求我们计算由空字符串 s 生成给定字符串 t 的不同方法数。允许的操作有两种:

  1. s 的末尾添加任意一个字母。
  2. 选择 s 中一个长度不小于 2 的后缀,并将其复制添加到 s 的末尾。

数据结构选择

我们选择使用一个数组 f 来记录生成 t 的前 i 个字符的不同方法数。f[i] 表示生成 t 的前 i 个字符的不同方法数。

算法步骤

  1. 初始化

    • f[0] = 1,因为生成空字符串只有一种方法。
  2. 动态规划转移

    • 对于每个位置 i,首先考虑通过添加一个字符来生成 t[i],即 f[i] = (f[i] + f[i-1]) % mod

    • 然后,检查是否可以通过复制后缀来生成 t[i]

      • 遍历所有可能的后缀长度 j,从 i-10
      • 检查后缀 t[j:i] 是否可以分成两段相同的部分(即 t[j:i]t[j:i] 的前半部分的重复)。
      • 如果可以,则 f[i] 可以加上 f[j + (i-j+1)/2 - 1]

具体实现

int mod = 1e9+7;
int solution(string t) {
    // write code here
    int n = t.size();
    vector<int> f(n,0);
    f[0]=1;
    for(int i=1;i<n;i++){
        // 添加一个字符
        f[i] = (f[i] + f[i-1])%mod;
        // 尝试复制后缀
        for(int j=i-1;j>=0;j--){
            // b表示能否通过复制后缀得到当前字符串
            bool b = true;
            if((i-j+1)%2==0){
                for(int k=0;k<(i-j+1)/2;k++){
                    if(t[i-k] != t[i-k-(i-j+1)/2]){
                        b = false;
                        break;
                    }
                }
            } else {
                b = false;
            }
            if(b){
                f[i] = (f[i] + f[j + (i-j+1)/2-1])%mod;
            }
        }
    }
    return f[n-1];
}

复杂度优化

但是我们总觉得时间复杂度不太对,特别是内层循环和字符串比较操作可能会导致时间复杂度较高,也许可以进一步优化

但是我们也没有比较好的思路,这时候就可以求助豆包MarsCode AI了:

image.png

可以看到,豆包MarsCode AI不仅指出了我们实现中的问题,而且针对性的给出了优化思路和优化步骤,那么就让我们根据豆包MarsCode AI给出的具体步骤优化我们的实现:

int mod = 1e9+7;
int solution(string t) {
    // write code here
    int n = t.size();
    vector<int> f(n,0);
    f[0]=1;

    // 字符串哈希预处理
    vector<long long> hash(n + 1, 0);
    vector<long long> pow(n + 1, 1);
    for (int i = 1; i <= n; ++i) {
        hash[i] = (hash[i - 1] * 26 + (t[i - 1] - 'a')) % mod;
        pow[i] = (pow[i - 1] * 26) % mod;
    }

    auto getHash = [&](int l, int r) {
        return (hash[r] - hash[l - 1] * pow[r - l + 1] % mod + mod) % mod;
    };

    for(int i=1;i<n;i++){
        // 添加一个字符
        f[i] = (f[i] + f[i-1])%mod;
        // 尝试复制后缀
        for(int j=i-1;j>=0;j--){
            if((i-j+1)%2==0){
                int mid = (i+j)/2;
                if(getHash(j+1, mid+1) == getHash(mid+2, i+1)){
                    f[i] = (f[i] + f[mid])%mod;
                }
            }
        }
    }
    return f[n-1];
}

成功通过本题:

image.png

总结

通过《小R的字符串生成方式》这道题目的深入解析与实现,我们深刻体会到了豆包MarsCode AI刷题平台的独特价值和显著优势。以下几点是豆包MarsCode AI在刷题过程中展现出来的亮点:

  1. 精准的问题诊断:在面对《小R的字符串生成方式》这样具有一定复杂度的问题时,豆包MarsCode AI能够迅速指出原有实现中的不足之处,特别是时间复杂度过高的问题。这种精准的诊断能力有助于开发者快速定位问题所在,避免盲目尝试。
  2. 高效的优化建议:针对发现的问题,豆包MarsCode AI提供了具体的优化方案,包括但不限于算法逻辑的调整和数据结构的选择。例如,通过减少不必要的字符串比较操作来降低时间复杂度,这些优化措施极大地提升了程序的执行效率。
  3. 易于理解的解释:豆包MarsCode AI不仅提供了优化方案,还详细解释了每一步优化背后的原理,使用户能够理解优化的本质,而不仅仅是机械地应用建议。这种教学式的支持有助于用户加深对相关知识点的理解,提高自我解决问题的能力。

综上所述,豆包MarsCode AI刷题平台通过其精准的问题诊断、高效的优化建议以及易于理解的解释,为用户创造了一个高效且互动性强的学习环境,特别适合希望提升编程能力和算法水平的学习者。

希望本文能激发更多人关注并尝试使用豆包MarsCode AI,共同享受编程带来的乐趣与成就。好了,那么我们这一次的解析就到这里,后面会给大家展示豆包MarsCode AI刷题的更多功能。