环绕字符串中唯一的子字符串

问题描述与解题思路

题目链接
在这里插入图片描述

确定本题的状态表示

记f[i]为字符串s中以s[i]为结尾的在base中出现的最长子字符串长度

确定本题的状态转移方程

	if(is_continuous(s[i-1],s[i])){
	    f[i]=f[i-1]+1;
	}else{
	    f[i]=1;
	}

填表求值

根据初始条件和状态转移方程,确定填表顺序,进而逐步填满dp表,最终返回题目要的结果

代码实现

class Solution {
public:
    bool is_continuous(char a,char b){
        return b-'a'==(a-'a'+1)%26;

    }
    int findSubstringInWraproundString(string s) {
        // 首先在base中出现的子串一定是连着的
        // 即如果s符合要求,那么对于任意的i,都有
        // s[i]-'a'=(s[i-1]-'a'+1)%26

        // 记f[i]为字符串s中以s[i]为结尾的在base中出现的最长子字符串长度
        int n=s.size();
        vector<int> f(n);
        vector<int> max_lenth(26,0);
        // 记录以a-z每个字母结尾的最长连续子字符串长度
        f[0]=1;
        max_lenth[s[0]-'a']=1;
        int ret=0;
        for(int i=1;i<n;i++){
            // cout << "s[i-1]=" << s[i-1]<< endl;
            // cout << "s[i]="<< s[i]<< endl;
            // cout << "is_continuous("<<s[i-1]<<","<<s[i]<<")="<<is_continuous(s[i-1],s[i])<< endl;
            if(is_continuous(s[i-1],s[i])){
                f[i]=f[i-1]+1;
            }else{
                // cout << "s[i-f[i-1]]-'a'="<<s[i-f[i-1]]-'a'<< endl;
                // cout <<"max_lenth["<< s[i-f[i-1]]-'a'<<"]="<< max_lenth[s[i-f[i-1]]-'a']<< endl;
                f[i]=1;
            }
            max_lenth[s[i]-'a']=max(max_lenth[s[i]-'a'],f[i]);
            // cout << "max_lenth["<<s[i]-'a'<<"]="<<max_lenth[s[i]-'a']<< endl;
        }
        // max_lenth[s[n-1]-'a']=max(max_lenth[s[n-1]-'a'],f[n-1]);
        for(int i=0;i<26;i++){
            ret+=max_lenth[i];
        }
        return ret;

    }
};
posted @ 2025-09-26 15:46  烧冻鸡翅QAQ  阅读(5)  评论(0)    收藏  举报  来源