技术提高是一个循序渐进的过程,所以我讲的leetcode算法题从最简单的level开始写的,然后到中级难度,最后到hard难度全部完。
目前我选择C语言,Python和Java作为实现语言,因为这三种语言还是比较典型的。由于篇幅和精力有限,其他语言的实现有兴趣的朋友请自己尝试。
初级难度说的差不多的时候,我打算再加点其他内容,我可能会从操作系统到协议栈,从分布式聊到大数据框架,从大数据聊到人工智能,... ...。
如果有任何问题可以在文章后评论或者私信给我。
我会持续分享下去,敬请您的关注。
LeetCode 796. 旋转字符串(Rotate String)
问题描述:
给定两个字符串, A 和 B。
A 的旋转操作就是将 A 最左边的字符移动到最右边。 例如, 若 A = 'abcde',在移动一次之后结果就是'bcdea' 。如果在若干次旋转操作之后,A 能变成B,那么返回
示例:
![efc772a64e8c815580dea3c5670982d4.png](https://i-blog.csdnimg.cn/blog_migrate/3efe24d9f4969217db91e43f350a867f.jpeg)
C语言实现:
题目的意思是将一个字符串A的开头的子串平移到字符串的末尾(也可以放过来说:将字符串的尾部的子串平移到开头)形成一个新的首尾相接的新字符串。这样的字符串有很多,判断B是否是其中的一个。
可能你第一个想法就是用KMP或者类似的字符串匹配算法来解这道题, 例如从B的第一个字a符开始,去A中查找第一个a所在的位置,然后查看后续的字符是否相等,如果不等,再从A的第二个字符a开始,直到某个a到A的结尾这段连续的子串都和B中开头的a的等长子串相等,再比较B的后续子串是否和A开头的子串相等。
具体的算法这里不展示了,我觉得这种算法比较复杂。但是时间复杂度应该可以达到O(n),空间复杂度O(1),性能应该不错。
其实这个这个题目有非常简单的解法:
如下图:
![8090b778bf12eb15a5d7016ba2fec77a.png](https://i-blog.csdnimg.cn/blog_migrate/df0faf19d7213803f731475ba813b3d6.jpeg)
如果我们将两个字符串A连接到一起组成新的字符串A+A,实际上就形成了首尾相接,如果将前面和后面多余的字符遮挡住,剩下的字符串就应该能找到B。换句话说,如果字符串B是A旋转后的字符串那么它一定在A+A中。
当然这种解法不要忘记了先要判断A和B的长度是否相等,如果B的长度和A不等,那就应该返回false。
最终代码如下:
![5f8e38c0977a61106ed361e500ada556.png](https://i-blog.csdnimg.cn/blog_migrate/fb3de3d30ca9729080d07dfa2ed795dc.jpeg)
这个算法足够简单,空间复杂度O(n),叠加的时间复杂度应该可以达到O(n)。
![ba9dba5ea6f0dfa6da6cfaa76a2755ce.png](https://i-blog.csdnimg.cn/blog_migrate/19ec35a532abd2a3773834a8ef5b0d9c.jpeg)
Java语言的实现:
Java 的实现和C语言的实现一致,不再撰述。
代码如下:
![cc0ffb5dbc6179fcdd5393f53ef6c4e5.png](https://i-blog.csdnimg.cn/blog_migrate/6ec82e720fef8e93f283f13c639dbfa7.jpeg)
![9d34b8c988cfaf8d607cffee241c8a44.png](https://i-blog.csdnimg.cn/blog_migrate/46f8763b5dffddf8a50acae4ae021901.jpeg)
python语言的实现:
python 的实现和C语言的实现一致,不再撰述。
代码如下:
![fe50650c2d4d2bb11825140fb3e7e449.png](https://i-blog.csdnimg.cn/blog_migrate/79eb16e5a5d3bdb189c9acde98326635.jpeg)
![756b84c6f505b0abac11c770440d13d1.png](https://i-blog.csdnimg.cn/blog_migrate/c9cc47d0cc261203e6d5f3948e20723a.jpeg)