【第八周】647. Palindromic Substrings

原题:

Given a string, your task is to count how many palindromic substrings in this string.

The substrings with different start indexes or end indexes are counted as different substrings even they consist of same characters.

Example 1:
Input: "abc"
Output: 3
Explanation: Three palindromic strings: "a", "b", "c".

Example 2:
Input: "aaa"
Output: 6
Explanation: Six palindromic strings: "a", "a", "a", "aa", "aa", "aaa".

leetcode地址:https://leetcode.com/problems/palindromic-substrings/description/

解题思路

题目大意:求一个字符串中所有回文子串的数目。

一个简单的算法:对所有子串进行检测是否为回文,复杂度为o(n^2),n为字符串长度;
不过这个算法没有充分利用回文串的特性:每一个长度大于2的回文串必定包含长度更小的回文串,例如字符串”abcba”是一个长度为5的回文串,这个回文串中还包含了长度为3的回文串”bcb”,而它又包含了“c”,它们都是回文串。

那么怎样才能利用这个隐藏的条件来设计算法呢?
通过观察可以发现,每一个回文串都有一个“对称中心”,例如“abcba”的“对称中心”就是’c’。在长度为偶数的回文串中,对称中心是最中间的两个字符,奇数串是最中间的那个字符。从对称中心向两端同时扩展,每延伸一位,就是一个新的回文串。
可以采用以下思路设计算法:先检测最基础的回文串,即长度为1或2的字符串。如果检测为是回文串,将此串向左右两端各拓展一位,继续检测,直到拓展后的字符串不是回文串为止。这样将所有基础回文串统计完毕后,所有长度大于2的回文串也统计到了。

代码

方法1

class Solution {
public:
    int countSubstrings(string s) {
        int res = 0;
        for (int i = 0; i < s.length(); i++) {
            for (int j = i; j < s.length(); j++) {
                if (s[i] == s[j]) {
                    if (isPalindromic(s.substr(i,j-i+1))) res++;
                }
            }
        }
        return res;
    }
    bool isPalindromic(string s) {
        for (int i = 0; i <= s.length() / 2; i++) 
            if (s[i] != s[s.length() -i -1]) return false;
        return true;
    }
};

方法2

class Solution {
public:
    int countSubstrings(string s) {
        int res = 0;
        for (int i = 0; i < s.length(); i++) {
            int start = i, end = i;
            while (start >= 0 && end < s.length() &&
                   isPalindromic(s.substr(start, end - start + 1))) {
                res++;
                start--;
                end++;
            }
            start = i, end = i + 1;
            while (start >= 0 && end < s.length() &&
                   isPalindromic(s.substr(start, end - start + 1))) {
                res++;
                start--;
                end++;
            }
        }
        return res;
    }
    bool isPalindromic(string s) {
        for (int i = 0; i <= s.length() / 2; i++) 
            if (s[i] != s[s.length() -i -1]) return false;
        return true;
    }
};

总结

1、字符串处理,善用堆栈思想。
2、动态规划

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值