LeetCode 算法:字符串轮转

139 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第 7 天,点击查看活动详情

字符串轮转

原题地址

字符串轮转。给定两个字符串 s1s2,请编写代码检查 s2 是否为 s1 旋转而成(比如,waterbottleerbottlewat 旋转后的字符串)。

示例1:

 输入:s1 = "waterbottle", s2 = "erbottlewat"
 输出:True

示例2:

 输入:s1 = "aa", s2 = "aba"
 输出:False

示例3:

 输入:s1 = "abcd", s2 = "acdb"
 输出:False

提示:

  • 字符串长度在[0, 100000]范围内。 说明:

  • 你能只调用一次检查子串的方法吗?

思路分析

方法一

  1. 首先,若两个字符串的长度不相同,那么无论如何都不可能旋转得到;
  2. 字符串 s1 + s1 中包含了所有可以通过 s1 旋转得到的子串,所以只需要判断 s2 是不是 s1 + s1 的子串即可。

方法二

  1. 若两个字符串的长度不相同,那么不管怎么样旋转都不可能实现,返回 false
  2. 若两个字符串相同,那么不用旋转即可得到,返回 true
  3. 除上述两种情况外,就需要寻找下字符串了,我们寻找的是以 s2 的首字母开头的 s1 可以旋转得到的字符串数组 strs,首先找到 s2 的首字母在 s1 中出现的下表位置 res,然后遍历 res,组装 strs,最后判断 strs 中是否含有 s2 即可。

AC 代码

方法一

/**
 * @param {string} s1
 * @param {string} s2
 * @return {boolean}
 */
var isFlipedString = function(s1, s2) {
    return s1.length === s2.length && (s1 + s1).indexOf(s2) !== -1
};

结果:

  • 执行结果: 通过
  • 执行用时:76 ms, 在所有 JavaScript 提交中击败了14.21%的用户
  • 内存消耗:41.4 MB, 在所有 JavaScript 提交中击败了51.09%的用户
  • 通过测试用例:31 / 31

方法二

/**
 * @param {string} s1
 * @param {string} s2
 * @return {boolean}
 */
var isFlipedString = function(s1, s2) {
    if(s1.length !== s2.length) return false
    if(s1 === s2) return true
    const res = []
    for(let i = 0; i < s1.length; i++) {
        if(s1[i] === s2[0]) {
            res.push(i)
        }
    }
    if(!res.length) return false
    const strs = []
    for(let i = 0; i < res.length; i++) {
        strs.push(s1.substring(res[i], s1.length) + s1.substring(0, res[i]))
    }
    return strs.includes(s2)
};

结果:

  • 执行结果: 通过
  • 执行用时:68 ms, 在所有 JavaScript 提交中击败了25.96%的用户
  • 内存消耗:43.7 MB, 在所有 JavaScript 提交中击败了19.40%的用户
  • 通过测试用例:31 / 31

END