给你一个字符串 s
,返回 s
中 长度为 3 的不同回文子序列 的个数。
即便存在多种方法来构建相同的子序列,但相同的子序列只计数一次。
回文 是正着读和反着读一样的字符串。
子序列 是由原字符串删除其中部分字符(也可以不删除)且不改变剩余字符之间相对顺序形成的一个新字符串。
- 例如,
"ace"
是"abcde"
的一个子序列。
示例 1:
输入:s = "aabca" 输出:3 解释:长度为 3 的 3 个回文子序列分别是: - "aba" ("aabca" 的子序列) - "aaa" ("aabca" 的子序列) - "aca" ("aabca" 的子序列)
示例 2:
输入:s = "adc" 输出:0 解释:"adc" 不存在长度为 3 的回文子序列。
示例 3:
输入:s = "bbcbaba" 输出:4 解释:长度为 3 的 4 个回文子序列分别是: - "bbb" ("bbcbaba" 的子序列) - "bcb" ("bbcbaba" 的子序列) - "bab" ("bbcbaba" 的子序列) - "aba" ("bbcbaba" 的子序列)
提示:
3 <= s.length <= 105
s
仅由小写英文字母组成
C++
class Solution {
public:
int countPalindromicSubsequence(string s) {
int ans=0;
unordered_map<char,vector<int>> mp;
for(int i=0;i<26;i++) {
char c='a'+i;
mp[c]={-1,-1};
}
int n=s.size();
for(int i=0;i<n;i++) {
vector<int> vec=mp[s[i]];
if(vec[0]==-1) {
mp[s[i]][0]=i;
} else {
mp[s[i]][1]=i;
}
}
for(int i=0;i<26;i++) {
vector<int> vec=mp['a'+i];
if(vec[1]-vec[0]>=2) {
unordered_set<char> st;
for(int k=vec[0]+1;k<vec[1];k++) {
st.insert(s[k]);
}
ans+=st.size();
}
}
return ans;
}
};
java
class Solution {
public int countPalindromicSubsequence(String s) {
int ans = 0;
int n = s.length();
for (int i = 0; i < 26; i++) {
char c = (char) (i + 'a');
int left = -1;
int right = -1;
for (int k = 0; k < n; k++) {
if (s.charAt(k) == c) {
if (left == -1) {
left = k;
} else {
right = k;
}
}
}
if (right - left >= 2) {
Set<Character> st = new HashSet<>();
for (int k = left + 1; k < right; k++) {
st.add(s.charAt(k));
}
ans += st.size();
}
}
return ans;
}
}
python
class Solution:
def countPalindromicSubsequence(self, s: str) -> int:
ans = 0
n = len(s)
ct = Counter()
for i in range(26):
c = chr(ord('a') + i)
ct[c] = (-1, -1)
for i in range(n):
vec = ct[s[i]]
if vec[0] == -1:
ct[s[i]] = (i, vec[1])
else:
ct[s[i]] = (vec[0], i)
for i in range(26):
vec = ct[chr(ord('a') + i)]
if vec[1] - vec[0] >= 2:
st = Counter(s[vec[0] + 1: vec[1]])
ans += len(st)
return ans