首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >天池 在线编程 回文子串(区间动态规划)

天池 在线编程 回文子串(区间动态规划)

作者头像
Michael阿明
发布2021-09-06 11:03:52
发布2021-09-06 11:03:52
3510
举报

1. 题目

描述

小明喜欢玩文字游戏,今天他希望在一个字符串的子串中找到回文串。

回文串是从左往右和从右往左读相同的字符串,例如121tacocat。子串是一个字符串中任意几个连续的字符构成的字符串。

现在给你一个字符串s, 求出s的回文串个数?

例如,s=mokkori。它的一些子串是[m,o,k,r,i,mo,ok,mok,okk,kk,okko],每个粗体元素都是s的一个回文子串,总共有7个不同的回文。

代码语言:javascript
复制
1 ≤ |s| ≤ 5000
Each character s[i] ∈ ascii[a-z]
代码语言:javascript
复制
示例
样例1:
输入: 
str = "abaaa"
输出:  
5
说明:
5个回文子串
a
aa
aaa
aba
b

样例2:
输入: 
str = "geek"
输出:  
4
说明:
4个回文子串
e
ee
g
k

https://www.lintcode.com/problem/837/description

2. 解题

  • 区间动态规划,dp[i][j] 表示字符子串 [i:j] 是否是回文串,采用 set 记录去重
代码语言:javascript
复制
class Solution {
public:
    /**
     * @param s: the string
     * @return: the number of substring
     */
    int countSubstrings(string &s) {
        // Write your code here.
        int n = s.size();
        vector<vector<int>> dp(n,vector<int>(n,0));
        set<char> set(s.begin(),s.end()); // 单个字符的子串
        unordered_set<string> oset;
        dp[0][0]=1;
        for(int i = 1; i < n; ++i)
        {
            dp[i][i] = 1; // 单个字符肯定是回文串
            if(s[i-1] == s[i])
            {
                dp[i-1][i] = 1;
                oset.insert(s.substr(i-1,2));
            }

        }
        
        for(int len = 2; len <= n; ++len)
        {
            for(int i = 0; i+len < n; ++i)
            {
                if(dp[i+1][i+len-1] && s[i] == s[i+len])
                {
                    dp[i][i+len] = 1;
                    oset.insert(s.substr(i,len+1));
                }
            }
        }
        return set.size() + oset.size();
    }
};

LintCode 837 :不要求去重

代码语言:javascript
复制
class Solution {
public:
    /**
     * @param str: s string
     * @return: return an integer, denote the number of the palindromic substrings
     */
    int countPalindromicSubstrings(string &s) {
        // write your code here
        int n = s.size();
        vector<vector<int>> dp(n,vector<int>(n,0));
        int ans = n;
        dp[0][0]=1;
        for(int i = 1; i < n; ++i)
        {
            dp[i][i] = 1;
            if(s[i-1] == s[i])
            {
                dp[i-1][i] = 1;
                ans++;
            }

        }
        
        for(int len = 2; len <= n; ++len)
        {
            for(int i = 0; i+len < n; ++i)
            {
                if(dp[i+1][i+len-1] && s[i] == s[i+len])
                {
                    dp[i][i+len] = 1;
                    ans++;
                }
            }
        }
        return ans;
    }
};

我的CSDN博客地址 https://michael.blog.csdn.net/

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2021/05/22 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1. 题目
  • 2. 解题
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档