Given a string S, find the number of different non-empty palindromic subsequences in S, and return that number modulo 10^9 + 7.
A subsequence of a string S is obtained by deleting 0 or more characters from S.
A sequence is palindromic if it is equal to the sequence reversed.
Two sequences A[1], A[2], … and B[1], B[2], … are different if there is some i for which A[i] != B[i].
注意事项
The length of S will be in the range [1, 1000].
Each character S[i] will be in the set {'a', 'b', 'c', 'd'}.
样例
Given S = "bccb", return 6
Explanation:
The 6 different non-empty palindromic subsequences are b, c, bb, cc, bcb, bccb.
Note that bcb is counted only once, even though it occurs twice.
Given S = "abcdabcdabcdabcdabcdabcdabcdabcddcbadcbadcbadcbadcbadcbadcbadcba" return 104860361
Explanation:
There are 3104860382 different non-empty palindromic subsequences, which is 104860361 modulo 10^9 + 7.
#ifndef C738_H
#define C738_H
#include<iostream>
#include<string>
#include<vector>
#include<algorithm>
using namespace std;
class Solution {
public:
/**
* @param str: a string S
* @return: the number of different non-empty palindromic subsequences in S
*/
int countPalindSubseq(string &str) {
// write your code here
if (str.empty())
return 0;
int len = str.size();
vector<vector<int>> dic(4, vector<int>());//存储a,b,c,d出现的位置
vector<vector<int>> nums(len + 1, vector<int>(len + 1, 0));
for (int i = 0; i < len; ++i)
dic[str[i] - 'a'].push_back(i);
return helper(str, dic, nums, 0, len);
}
int helper(string &str, vector<vector<int>> dic, vector<vector<int>> &nums, int start, int end)
{
if (start >= end)
return 0;
if (nums[start][end] > 0)//表示当前位置已经计算过
return nums[start][end];
long long res = 0;
for (int i = 0; i < dic.size(); ++i)
{
if (dic[i].empty())//表示字母在对应的数组中没有值
continue;
//查找第一个不小于start的位置和第一个小于end的位置
auto it_start = lower_bound(dic[i].begin(), dic[i].end(), start);
auto it_end = lower_bound(dic[i].begin(), dic[i].end(), end) - 1;
//若当前区间内没有此字母
if (it_start == dic[i].end() || *it_start >= end)
continue;
res++;
//若it_start,it_end指向不同的字母
if (it_start != it_end)
res++;
res += helper(str, dic, nums, *it_start + 1, *it_end);
}
//为防止超出范围,取余
nums[start][end] = res % (int)(1e9 + 7);
return nums[start][end];
}
};
#endif