leetcode 5809. 长度为 3 的不同回文子序列

leetcode 5809. 长度为 3 的不同回文子序列

给你一个字符串 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 <= 10^5
  • s 仅由小写英文字母组成

方法一:

思路:找到每个字符第一个索引位置 left 和最后一个索引位置 right,然后在(left, right)区间内计算字符种类的个数。

class Solution {
public:
    int countPalindromicSubsequence(string s) {
        int n = s.size();
        int res = 0;
        //保存每个字符的firstIndex和lastIndex
        vector<pair<int, int>> hash(26, {-1, -1});
        for(int i=0; i<n; i++){
            if(hash[s[i] - 'a'].first != -1){
                hash[s[i] - 'a'].second = i; 
            }
            else{
                hash[s[i] - 'a'].first = i;
            }
        }
        //遍历26个字符
        for(int i=0; i<26; i++){
            int left = hash[i].first;
            int right = hash[i].second;
            int cnt[26] = {0};
            //计算中间的字符种类个数
            for(int k=left+1; k<right; k++){
                cnt[s[k] - 'a'] = 1;
            }
            for(int i=0; i<26; i++){
                res += cnt[i];
            }
        }
        return res;
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值