算法练习:回文子字符串的个数(多种方法)

一.前言

今天介绍一道相对简单的练习题,同样是来自LeetCode。

回文子字符串的个数,给定一个字符串 s ,请计算这个字符串中有多少个回文子字符串。具有不同开始位置或结束位置的子串,即使是由相同的字符组成,也会被视作不同的子串。

示例1:

输入:s = "abc"
输出:3
解释:三个回文子串: "a", "b", "c"

示例2:

输入:s = "aaa"
输出:6
解释:6个回文子串: "a", "a", "a", "aa", "aa", "aaa"

题目来源:LeetCode

二.题解

其实关于回文的题有很多种,而解法更是多种多样,今天介绍两种方法,递归中心拓展

1.递归

简单来说递归就是一个函数调用自己本身的行为就叫递归。递归具有代码简洁,易读的特点,但是缺点也不容忽视:

a).运行效率较低。
b).可能会导致栈溢出,如果递归次数太多,需要在内存栈中分配空间以保存参数以及临时变量就会过多,当超出栈的容量,就会导致栈溢出。

我们思路是这样的:首先通过遍历找到所有的子串,然后再判断子串是否是回文。那么怎么判断是否是回文呢?比如这样的一个字符串abcba,我们判断其是否为回文,可以先判断第一个和最后一个字符是否相同,再判断第二个字符和倒数第二个字符是否相同...直到全部判断完毕,这个过程中,我们反复做着相同的工作,因此可以使用递归,来看看代码吧:

class Solution {
    public int countSubstrings(String s) {
        int result = 0;//最终结果
        //两层循环,从字符串首部开始遍历处所有子字符串
        for (int i = 0; i < s.length(); i++) {
            for (int j = i; j < s.length(); j++) {
                //每个子字符串调用isHuiwen,若返回 true 则 result + 1
                if (isHuiwen(s, i, j)) {
                    result++;
                }
            }
        }
        return result;
    }
    //isHuiwen需要三个参数,s 是字符串,i 是子字符串第一个字符,j 是子字符串的最后一个字符
    public static boolean isHuiwen(String s, int i, int j) {
        //两种情况返回true(1,2)
        //1.当子字符串的长度是奇数时,此时回文中心只有一个,当递归到 i == j时,说明全部首尾字符判断完毕,全部相等,返回true
        if (i == j) return true;
        else {
            if (s.charAt(i) != s.charAt(j)) {
                //如果二者不相等,直接返回false,退出递归
                return false;
            } else {
                //2.当子字符串的长度为偶数,此时回文中心是两个字符,由于上面的if中已经判断 i 和 j是相同的
                //因此到这里也将首尾字符全部判断完毕,全部相等,返回true
                if (i + 1 == j) {
                    return true;
                } else return isHuiwen(s, ++i, --j);
                //如果程序走到这儿,说明不满足上面任意一种情况,因此在调用函数进一步判断 ++i 和 --j 是否相等
            }
        }
    }
}

我们上面这种方法找出子字符串需要两层循环,时间复杂度为O(n^2) 而判断它是否为回文又是O(n),因此总的复杂度为O(n^3)。显然效率不高,那我们再来看看LeetCode官方题解吧!——中心拓展

2.中心拓展

大致思路:我们从每一个可能成为回文中心的点开始,若前后字符相等就拓展,反之,则停止拓展。

当子字符串是奇数时,回文中心是一个;当子字符串是偶数个时,回文中心是两个。有没有一种方法可以统一二者呢?答案是有的。通过规律我们可以发现:无论子字符串长度是偶数还是奇数,我们都需要遍历 2n - 1 次字符串,换句话说就是有 2n - 1 个回文中心,

class Solution {
    public int countSubstrings(String s) {
        int n = s.length(), ans = 0;
        for (int i = 0; i < 2 * n - 1; ++i) {
            //向前拓展从i开始,向后拓展从r开始
            int l = i / 2, r = i / 2 + i % 2;
            //当子字符串个数为偶数时,i 和 r 相等 
            while (l >= 0 && r < n && s.charAt(l) == s.charAt(r)) {
                //当前后字符相等且 i 和 r 未越界时
                //开始向两边拓展
                --l;
                ++r;
                ++ans;
            }
        }
        return ans;
    }
}

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,189评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,577评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,857评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,703评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,705评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,620评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,995评论 3 396
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,656评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,898评论 1 298
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,639评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,720评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,395评论 4 319
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,982评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,953评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,195评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,907评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,472评论 2 342

推荐阅读更多精彩内容