怎么判断一个字符串的最长回文子串是否在头尾_【Leetcode每日打卡】最长回文串...

d5c40572-7513-eb11-8da9-e4434bdf6706.png

干货预警:所有文章都会首发于我的公众号【甜姨的奇妙冒险】,欢迎watch。

d6c40572-7513-eb11-8da9-e4434bdf6706.png

一、来历:

力扣从3月开始开启了每日一题打卡活动,于是跟风加入了打卡大军,这两天写评论、发题解,没想到反响还不错,收到了来自很多同学的鼓励与好评,短短几天就170的关注了,有的同学说每天都会蹲我的评论和题解哈哈 ,本来觉得wx公众号是比较私人的趣味(つд⊂),但不由萌生了在公众号开一个专栏写每日一题的想法,有啥问题或想法可以私信我,anytime。本文重点在第五部分细节说明。

二、原题描述:

d8c40572-7513-eb11-8da9-e4434bdf6706.png

三、题目分析:

这题是道简单的构造性题目,只需要尽可能的左右对称地构造字符串就行了。所以最终的回文串中所有的字符都左右对称地出现了偶数次(对于奇数长度的回文串,最中间的那个字符可以出现奇数次)。

比如偶数长度的回文串 “abba”,每个字符都出现了偶数次;

比如奇数长度的回文串“abcbcbcba”,c出现了奇数次,其它字符都出现了偶数次。

四、AC代码:

class 

再提供Java8的流式写法:

class 

五、细节说明(咳咳..划重点~~)

代码本身很简单,但有很多细节我觉得才是最重要的。【一脸认真哦 ξ( ✿>◡❛)

1. 计数为啥用数组?

counter计数是很常见的场景了,对于数据范围有限的计数,直接用数组就行了,看见很多同学用的HashMap,额外增加了hash的计算成本、链表(树)Node的创建开销等,在时间、空间上都不讨好哟。

2. 为啥counter数组的长度是58?

因为A~z的范围是'z' - 'A' + 1= 122 - 65 + 1 = 58,打印看看就知道了(但我觉得常见的几个ascii码记住的话日常会方便很多哟,比如'A'是65,'a'是97)。

3. x - (x & 1) 是什么意思?

合理的运用位运算可以让代码减少一些不必要的判断分支。

如果 x 是奇数,x & 1 的结果就是1,偶数就是0,实现了偶数不变、奇数减1的逻辑。当然这里还有另外一种位运算写法: (x >> 1) << 1 ,先右移一位去掉最末位的0或1,再左移一位,也实现了偶数不变、奇数减1的逻辑。

4. 这里为啥不写成x - x % 2?

取模是一个消耗较大的操作,因此大多数语言的编译器比如C++都对模运算进行了优化,比如可以将 x%2 优化成 x&1,这种情况下怎么写都一样啦。但是Java比较特殊,Java中是不存在无符号整型的,数字是用补码来表示的(大家还记得补码吧...最高位是符号位,0表示正数,1表示负数),所以对于负数来说,%2 与 &1 两个操作是完全不同的(如下):

int 

因此我觉得jvm很难对模运算进行优化(当然也有可能优化,比如先判断一下是不是正数,但我觉得这么麻烦的话,可能并没有优化 )总之,结论就是:能用 & 就不要取模。这里提一下一个常见的规律,对于模数是2的幂的情况下,都可以优化成&运算,如下:

int 

5. 流式写法看不懂?以及流式写法这里为啥慢?

s.chars()的返回值是一个 IntStream,就是Int的流;

.boxed()会装箱返回Stream<Integer>;

.collect()是聚合的算子,Collectors.toMap的三个参数分别是 keyMapper,valueMapper 和 mergeFunction。分别表示聚合出来的 Map 的 key 是什么,value 是什么,如果遇到key相同的,怎么合并值。

counter.values() 返回的是map值的集合Collection<Integer>,先用.stream()转成流以后,利用mapToInt 转成 IntStream,因为 IntStream 是支持 sum 算子的,通过sum算子进行求和。

最后,至于为啥这里流运算比传统循环慢,是因为对于小数据集无法发挥流的优势,这里只是为了介绍这种优雅的写法。

六、类似题目

Easy:

1. 判断是否是回文串(125. 验证回文串)

2. 判断是否是回文链表 (234. 回文链表)

3. 判断是否是回文数 (9. 回文数)

Medium:

4. 符串里有多少个回文子串(647. 回文子串)

5. 找到最长的回文子串(5. 最长回文子串)

关于 最长回文子串, 还有一个特定的算法叫做 Manacher算法,该算法巧妙地利用插入不存在的字符将回文串都转成奇数回文串,比如abba变成了#a#b#b#a#(字符串中心是#), abcba变成了#a#b#c#b#a#(字符串中心是c) ,有兴趣的同学可以去学习学习~


以上,蟹蟹宝宝们的观看~(๑ơ ₃ ơ)♥

恕我直言,在座的各位都是dalao!!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值