LC 796. 旋转字符串
题目描述
这是 LeetCode 上的 796. 旋转字符串 ,难度为 简单。
给定两个字符串,s
和 goal
。如果在若干次旋转操作之后,s
能变成 goal
,那么返回 true
。
s
的旋转操作就是将 s
最左边的字符移动到最右边。
- 例如, 若
s = 'abcde'
,在旋转一次之后结果就是'bcdea'
。
示例 1:1
2
3输入: s = "abcde", goal = "cdeab"
输出: true
示例 2:1
2
3输入: s = "abcde", goal = "abced"
输出: false
提示:
- $1 <= s.length, goal.length <= 100$
s
和goal
由小写英文字母组成
模拟
由于每次旋转操作都是将最左侧字符移动到最右侧,因此如果 goal
可由 s
经过多步旋转而来,那么 goal
必然会出现在 s + s
中,即满足 (s + s).contains(goal)
,同时为了 s
本身过长导致的结果成立,我们需要先确保两字符串长度相等。
代码:1
2
3
4
5class Solution {
public boolean rotateString(String s, String goal) {
return s.length() == goal.length() && (s + s).contains(goal);
}
}
- 时间复杂度:$O(n)$
- 空间复杂度:$O(n)$
关于 contains
操作的复杂度说明
看到不少同学对 contains
的复杂度写成 $O(n)$ 有疑问。
在 Java 中,contains
实际最终是通过 indexOf(char[] source, int sourceOffset, int sourceCount, char[] target, int targetOffset, int targetCount, int fromIndex)
来拿到子串在原串的下标,通过判断下标是否为 $-1$ 来得知子串是否在原串出现过。
我们知道一个较为普通的子串匹配算法的复杂度通为 $O(n*k)$,其中 $n$ 和 $k$ 分别是原串和子串的长度,而一些复杂度上较为优秀的算法可以做到 $O(n + k)$,例如 KMP。
从复杂度上来看 KMP 似乎要更好,但实际上对于 indexOf
这一高频操作而言,KMP 的预处理逻辑和空间开销都是不可接受的。
因此在 OpenJDK 中的 indexOf
源码中,你看不到诸如 KMP 这一类「最坏情况下仍为线性复杂度」的算法实现。
但是 contains
的复杂度真的就是 $O(n * k)$ 吗?
其实并不是,这取决于 JVM 是否有针对 indexOf
的优化,在最为流行 HotSpot VM 中,就有对 indexOf
的优化。
使用以下两行命令执行 Main.java
,会得到不同的用时。
1 |
|
环境说明:1
2
3
4➜ java -version
java version "1.8.0_131"
Java(TM) SE Runtime Environment (build 1.8.0_131-b11)
Java HotSpot(TM) 64-Bit Server VM (build 25.131-b11, mixed mode)
先执行 javac Main.java
进行编译后:
- 使用原始的
indexOf
实现进行匹配(执行多次,平均耗时为基准值 $X$):1
java -XX:+UnlockDiagnosticVMOptions -XX:DisableIntrinsic=_indexOf Main
- 使用 HotSpot VM 优化的
indexOf
进行匹配(执行多次,平均耗时为基准值 $X$ 的 $[0.55, 0.65]$ 之间):1
java Main
因此实际运行的 contains
操作的复杂度为多少并不好确定,但可以确定是要优于 $O(n * k)$ 的。
最后
这是我们「刷穿 LeetCode」系列文章的第 No.796
篇,系列开始于 2021/01/01,截止于起始日 LeetCode 上共有 1916 道题目,部分是有锁题,我们将先把所有不带锁的题目刷完。
在这个系列文章里面,除了讲解解题思路以外,还会尽可能给出最为简洁的代码。如果涉及通解还会相应的代码模板。
为了方便各位同学能够电脑上进行调试和提交代码,我建立了相关的仓库:https://github.com/SharingSource/LogicStack-LeetCode 。
在仓库地址里,你可以看到系列文章的题解链接、系列文章的相应代码、LeetCode 原题链接和其他优选题解。
本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!