问题146 字符串首尾相同子序列计数 | 豆包MarsCode AI刷题

82 阅读2分钟

问题描述

小M拿到了一个仅由小写字母组成的字符串,她想知道在这个字符串中,有多少个子序列的首尾字符相同。子序列的定义是:从原字符串中按原顺序取出若干字符(可以不连续)组成的新字符串。

例如,对于字符串 "arcaea",其子序列包括 "aca", "ara", "aaa" 等,这些子序列的首尾字符都是相同的。

你需要计算满足这一条件的子序列数量,并输出对 998244353998244353 取模的结果

思路

首先,对于每一个首尾相同的字符串子序列,不妨设其起始和终止的字母的坐标为i,j。则可知:

  • i <= j
  • s[i] == s[j]
  • 假设j和i之间有n个数,则存在2^(n)个以i,j开头结尾的满足要求的子序列

所以我们可以记住每一个字母的全部出现坐标,再计算所有可能的i,j组的计数 最后,不要忘记每一个字母单拿出来也是一个答案(即i==j),要特殊的考虑。

代码示例
int M = 998244353;
long time(long a, long b) {
    return (a*b)%M;
}
long add(long a, long b) {
    return (a+b)%M;
}

int solution(std::string s) {
    if(!s.size()) {
        return 0;
    }
    vector<int> pow2(s.size());
    pow2[0]=1;
    for(int i=1;i<s.size();i++) {
        pow2[i] = time(pow2[i-1],2);
    }
    int res = s.size();
    vector<vector<int>> pos(26);
    for(int i=0;i<s.size();i++) {
        for(auto x:pos[s[i]-'a']) {
            res = add(res,pow2[i-x-1]);
        }
        pos[s[i]-'a'].push_back(i);
        //cout << i <<" " <<res <<"\n";
    }
    return res;
}
代码示例

int M = 998244353; long time(long a, long b) { return (a*b)%M; } long add(long a, long b) { return (a+b)%M; }

int solution(std::string s) { if(!s.size()) { return 0; } vector pow2(s.size()); pow2[0]=1; for(int i=1;i<s.size();i++) { pow2[i] = time(pow2[i-1],2); } int res = s.size(); vector<vector> pos(26); for(int i=0;i<s.size();i++) { for(auto x:pos[s[i]-'a']) { res = add(res,pow2[i-x-1]); } pos[s[i]-'a'].push_back(i); //cout << i <<" " <<res <<"\n"; } return res; } int M = 998244353; long time(long a, long b) { return (a*b)%M; } long add(long a, long b) { return (a+b)%M; }

int solution(std::string s) { if(!s.size()) { return 0; } vector pow2(s.size()); pow2[0]=1; for(int i=1;i<s.size();i++) { pow2[i] = time(pow2[i-1],2); } int res = s.size(); vector<vector> pos(26); for(int i=0;i<s.size();i++) { for(auto x:pos[s[i]-'a']) { res = add(res,pow2[i-x-1]); } pos[s[i]-'a'].push_back(i); //cout << i <<" " <<res <<"\n"; } return res; } int M = 998244353; long time(long a, long b) { return (a*b)%M; } long add(long a, long b) { return (a+b)%M; }

int solution(std::string s) { if(!s.size()) { return 0; } vector pow2(s.size()); pow2[0]=1; for(int i=1;i<s.size();i++) { pow2[i] = time(pow2[i-1],2); } int res = s.size(); vector<vector> pos(26); for(int i=0;i<s.size();i++) { for(auto x:pos[s[i]-'a']) { res = add(res,pow2[i-x-1]); } pos[s[i]-'a'].push_back(i); //cout << i <<" " <<res <<"\n"; } return res; }