一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第7天,点击查看活动详情。
每日刷题 2021.04.07
- leetcode原题链接:leetcode-cn.com/problems/ro…
- 难度:简单
- 方法:字符串方法
题目
- 给定两个字符串, s 和 goal。如果在若干次旋转操作之后,s 能变成 goal ,那么返回 true 。
- s 的 旋转操作 就是将 s 最左边的字符移动到最右边。
- 例如, 若 s = 'abcde',在旋转一次之后结果就是'bcdea' 。
示例
- 示例1
输入: s = "abcde", goal = "cdeab"
输出: true
- 示例2
输入: s = "abcde", goal = "abced"
输出: false
提示
1 <= s.length, goal.length <= 100s和goal由小写英文字母组成
解题思路
- 首先:想到的是双指针做法
- 其次又想到了字符串方法
slice() - 虽然两个做法不同,但是思路是一样的。既然
goal是通过s旋转得来的,那么只要在goal中找到s的开头,下标记为index。从index开始截取到goal的末尾,再从goal的开头截取到index - 1,将两段字符串进行拼接,如果能够组成s那么就返回true,否则返回false - 注意⚠️:如果只是用
s开头的一个字母作为基准,那么在goal中可能存在多个相似的,因此需要将每一个都试一遍。如果遇到可以匹配成功的,那么就返回true;如果所有的情况都遍历完,没有符合的就返回false
学习题解(妙啊)
- 两个字符串
s相加,那么(s + s).container(goal)
回顾kMP算法
KMP本质是:优化常规做法中,每次都从头比较匹配串的操作。如何快速在原串中找到匹配字符串的下标。kmp因为在非完全匹配的过程中(即:失败的匹配过程中),提取有效信息进行复用,以此来减少重复的匹配操作,优化时间复杂度。kmp核心思想:不相等时,回退。- 主要分为
2部分:- 匹配串的
next数组 - 原串和匹配串的匹配过程
- 匹配串的
- 第一部分:
next数组- 匹配串和自身进行匹配,所形成的数组。
- 首先我们要明白两个概念:前缀:一个字符串中不包含最后一个元素的连续的子串;后缀:一个字符串中不包含最开始一个元素的连续的子串
- 举例:字符串:
bkdjsbk,其前缀[b,bk,bkd,bkdj,bkdjs,bkdjsb];后缀:[k,bk,sbk,jsbk,djsbk,kdjsbk]。比较前缀集合和后缀集合,从中找到相等的最长的子串bk
- 举例:字符串:
- 现在我们知道了最长相等前缀是什么含义后。
- 第二部分:原串和匹配串的匹配过程
- 方法与求解
next数组的方法相似
- 方法与求解
AC代码
var rotateString = function(s, goal) {
// 旋转字符串:双指针可以呀
// 所有相同的开头可以查一下
let len = s.length;
function isVerse(l) {
// 当前给的l就是第一个匹配成功的字符
// 拼接字符串
let str = goal.slice(l) + goal.slice(0,l)
if(str === s) return true;
return false;
}
for(let i = 0; i < len; i++) {
if(goal[i] == s[0]){
if(isVerse(i)) return true;
}
}
return false;
};
总结
- 本题也可以使用
kmp算法