【完虐算法】字符串-旋转词 复盘总结

大家好吖,我是Johngo!

有几天没有更新文章了,居然把前几天的送书的事情忘记了。

今天一起吧!!

说在前面

言归正传,这一期来说说字符串的第三块内容「字符串 - 旋转词」

github:https://github.com/xiaozhutec/share_leetcode

文档地址:https://github.com/xiaozhutec/share_leetcode/tree/master/docs

整体架构:

【完虐算法】字符串-旋转词 复盘总结

字符串 - 旋转词

今天这期内容是字符串的第三期。

首先,把什么是旋转词进行一个简单的说明:

所谓字符串的旋转,分为左右旋转。

以左旋转为例:就是把字符串前面的若干字符转移到字符串的尾部这样的操作

比如说字符串 "abcdefg" 左旋转 2 个三位,得到字符串 "abcdefg"。

字符串「旋转词」方面的问题(还拿字符串 "abcdefg" 和 "cdefgab" 为例)

令 A = "abcdefg",B = "cdefgab"

一般的思路是:

将 A = A+A,判断 字符串 B 是否被包含进去字符串 A+A。

下图为例,将 A 做 A = A+A 的操作,形成一个大字符串

【完虐算法】字符串-旋转词 复盘总结

之后,判断字符串 B 是否被包含进上图中的大字符串即可解决。

【完虐算法】字符串-旋转词 复盘总结

发现,正好匹配,问题解决!

说明字符串 A 和字符串 B 互为旋转词。

案例

整体关于字符串「旋转词」方面的问题是比较简单的,个人认为只要掌握其一般思路即可。

下面会通过两个案例进行举例,分别是 LeetCode 的 796 题剑指 Offer 58 题

796.旋转字符串【简单】

剑指 Offer 58 - II. 左旋转字符串【简单】

796.旋转字符串【简单】

给定两个字符串, A 和 B。

A 的旋转操作就是将 A 最左边的字符移动到最右边。 例如, 若 A = 'abcde',在移动一次之后结果就是'bcdea' 。如果在若干次旋转操作之后,A 能变成B,那么返回True。

输入: A = 'abcde', B = 'cdeab'
输出: true

整体这个题目还是比较简单的,解决的思路就是上述介绍的方式。

即 字符串 A+A 包含字符串 B:

【完虐算法】字符串-旋转词 复盘总结

实现起来也很简单,就一行即可。

咱们直接用 Python 来解决:

class Solution(object):
    def rotateString(self, s, goal):
        return len(s) == len(goal) and s in goal+goal

在这里利用了 Python 固有的方式,可以进行子串判断。

事实上,还有一种算法咱们是需要着重掌握的,那就是著名的 KMP 算法。

KMP 算法是专门用来判断子串判断的算法,后面有一期会非常详细的就 KMP 进行分享。

剑指 Offer 58 - II. 左旋转字符串【简单】

字符串的左旋转操作是把字符串前面的若干个字符转移到字符串的尾部。请定义一个函数实现字符串左旋转操作的功能。比如,输入字符串"abcdefg"和数字2,该函数将返回左旋转两位得到的结果"cdefgab"。

输入: s = "abcdefg", k = 2
输出: "cdefgab"

这个题目虽然也是标记的简单,但需要加一步骤,就是给定的 k 值。

也可以分为两种思路解决。

方法一:s2 = s + s,得到s[k, size(s)+k]即为原字符串 s 旋转了 k 个位置的旋转词

方法二:将字符串的 s 的前 k 位复制一份接到字符串 s 的最后,得到 s[k:] 为 s 旋转了 k 个位置的旋转词

好!先来看看方法一:

拼接字符串 s,然后当 k=2的时候,截取固定长度(字符串 s 的长度)。

【完虐算法】字符串-旋转词 复盘总结

最后返回截取的字符串,得到答案。

看超级简约的代码:

class Solution(object):
    def reverseLeftWords(self, s, n):
        size = len(s)
        s2 = s + s
        return s2[n:size+n]

或者再简约点:

class Solution(object):
    def reverseLeftWords(self, s, n):
        s2 = s + s
        return s2[n:len(s)+n]

再看方法二:

将前 k 个元素,依次接到字符串 s 的后边。

进而获取固定长度(字符串 s 的长度)的字符串,得到答案。

【完虐算法】字符串-旋转词 复盘总结

简洁的代码来了:

class Solution(object):
    def reverseLeftWords1(self, s, n):
        size = len(s)
        for i in range(n):
            s += s[i]
        return s[n:]

还可以更加简洁一些, 即不用循环,直接截取前 k 个字符拼接到 s 的最后即可!

好了,今天内容比较简单一些。就是关于字符串「旋转词」进行了分享。

另外,方便的话也在我的github

上一篇:acwing第 24 场周赛


下一篇:题解[ABC221G Jumping sequence]