一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第6天,点击查看活动详情。
每日一题,起飞
旋转字符串
该题出自力扣的796题 —— 旋转字符串【简单题】
审题
给定两个字符串, s 和 goal。如果在若干次旋转操作之后,s 能变成 goal ,那么返回 true 。
s 的 旋转操作 就是将 s 最左边的字符移动到最右边。
例如, 若 s = 'abcde',在旋转一次之后结果就是'bcdea' 。
- 该题的题意也很简单,其实就是找出字符串是否存在指定子字符串
- 若字符末尾可以连上头指针,存在子字符串,即为旋转字符成功
- 解法一:
- 首先确认字符串的长度是否 == 子字符串长度
- 因为要首尾相连,所以字符串+字符串 = 新的2倍字符串
- 新的2倍长字符串是否包含子字符串
- 同时满足条件即为true
- 时间复杂度O(n)
- 空间复杂度O(n)
- 解法二:暴力解法
- 直接每个字符每个字符去对应,双重for循环
- 时间复杂度拉满
- 该题也可以衍生出KMP解法
- 是否存在子字符串
- KMP算法
- 这边再讲一下,如果使用解法一,那么势必会用到String的contains方法
- contains的实现是由indexOf方法实现的
indexOf(s.toString()) > -1;-
本质上还是通过indexOf(char[] source, int sourceOffset, int sourceCount, char[] target, int targetOffset, int targetCount, int fromIndex) 方法来拿到子字符串在原字符串的下标,通过判断下标是否为 −1 来得知子串是否在原串出现过。
-
从时间复杂度上面来分析的话,KMP算法实现肯定会好一点,毕竟不需要重新遍历,但是对于indexOf方法来说,频繁的调用,对于KMP算法的预处理(也就是next表)和空间消耗都是奢侈的。
编码
class Solution {
public boolean rotateString(String s, String goal) {
return s.length() == goal.length() && (s+s).contains(goal);
}
}