做法一(时间复杂度o(n),空间复杂度o(1))

首先如果一个单词中没有重复字母是一个比较简单的dp问题。比如如果找单词为“air”的子序列,我们只需要开一个dp[3]数组,dp[0]记录前面“a”的个数,dp[1]记录前面为“ai”的个数,dp[2]记录前面“air”的个数即可,更新分别以dp[0]++;dp[1]+=dp[0];dp[2]+=dp[1]进行顺序的更新即可,显然最后dp[2]即是我们想要的答案。但是我们这次要找的子序列“warrant”中有重复字母,不能像上面一样简单的更新。不过可以运用上面的思想,对于出现多次的字母,我们先更新后面的再更新前面的,这样就可以避免重复计算。代码如下:

const int maxn=2e6+5;
const int mode=1e9+7;
int dp[7];
class Solution {
public:
    /**
     * 返回答案对1e9+7取模后的值
     * @param str string字符串 
     * @return int整型
     */
    int numberofanswer(string str) {
        // write code here
        int i,n;  
        n=str.size();
        long long sum=0;
        for(i=0;i<n;i++)
        {
            if(str[i]=='w')dp[0]++;
            else if(str[i]=='a'){dp[4]+=dp[3];dp[1]+=dp[0];dp[4]%=mode;dp[1]%=mode;}
            else if(str[i]=='r'){dp[3]+=dp[2];dp[2]+=dp[1];dp[2]%=mode;dp[3]%=mode;}
            else if(str[i]=='n'){dp[5]+=dp[4];dp[5]%=mode;}
            else if(str[i]=='t'){dp[6]+=dp[5];dp[6]%=mode;}
        }
        return dp[6];
    }
};

做法二(时间复杂度o(n),空间复杂度o(n))

当然,如果想不明白更新顺序的话,也可用其他办法处理相同字母的问题,这里提供其中的一种方法。我们可以一单词的第二个r为分界点。把单词分为三部分“war”+“r”+“ant”,这样这三个部分都没有重复字母,然后我们枚举每个r,计算它当第二个r的权值,即前缀“war”的个数乘上后缀“ant”的个数,求和后即为我们要的答案。代码如下:

const int maxn=2e6+5;
const long long mode=1e9+7;
long long qz[maxn];
long long hz[maxn];
int dp[2];
class Solution {
public:
    /**
     * 返回答案对1e9+7取模后的值
     * @param str string字符串 
     * @return int整型
     */
    int numberofanswer(string str) {
        // write code here
        int i,n;  
        n=str.size();
        long long sum=0;
        for(i=0;i<n;i++)
        {
            if(str[i]=='w')dp[0]++;
            else if(str[i]=='a'){dp[1]+=dp[0];dp[1]%=mode;}
            else if(str[i]=='r'){sum+=dp[1];sum%=mode;}
            qz[i]=sum;
        }
        sum=0;
        dp[0]=dp[1]=0;
        for(i=n-1;i>=0;i--)
        {
            if(str[i]=='t')dp[0]++;
            else if(str[i]=='n'){dp[1]+=dp[0];dp[1]%=mode;}
            else if(str[i]=='a'){sum+=dp[1];sum%=mode;}
            hz[i]=sum;
        }
        sum=0;
        for(i=2;i<n-2;i++)
        {
            if(str[i]=='r')
            {
                sum+=qz[i-1]*hz[i+1];
                sum%=mode;
            }
        }  
        int sum2=sum;
        return sum2;
    }
};