算法小知识-----04.07-----旋转字符串

77 阅读2分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第6天,点击查看活动详情

每日一题,起飞

旋转字符串

该题出自力扣的796题 —— 旋转字符串【简单题】

审题

给定两个字符串, s 和 goal。如果在若干次旋转操作之后,s 能变成 goal ,那么返回 true 。
s 的 旋转操作 就是将 s 最左边的字符移动到最右边。 
例如, 若 s = 'abcde',在旋转一次之后结果就是'bcdea' 。

image.png

  • 该题的题意也很简单,其实就是找出字符串是否存在指定子字符串
  • 若字符末尾可以连上头指针,存在子字符串,即为旋转字符成功
  • 解法一:
    • 首先确认字符串的长度是否 == 子字符串长度
    • 因为要首尾相连,所以字符串+字符串 = 新的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);
    }
}

image.png