leetcode
leetcode 701 ~ 750
旋转字符串

旋转字符串

难度:

标签:

题目描述

代码结果

运行时间: 19 ms, 内存: 15.9 MB


/*
 * 使用Java Stream实现
 * 思路同Java解法:
 * 1. 检查长度是否一致
 * 2. 拼接s本身,并判断goal是否是拼接结果的子串
 */

import java.util.stream.IntStream;

public class SolutionStream {
    public boolean rotateString(String s, String goal) {
        return s.length() == goal.length() &&
               IntStream.range(0, s.length())
                        .anyMatch(i -> (s + s).substring(i, i + goal.length()).equals(goal));
    }
}

解释

方法:

这个题解采用了一种简单直接的方法来解决旋转字符串的问题。首先,它检查原字符串s和目标字符串goal是否相等,如果相等则直接返回true。如果不相等,它会遍历字符串s的每个位置,从每个位置分别进行一次旋转,即把从当前位置到字符串末尾的子字符串放到前面,从字符串开头到当前位置的子字符串放到后面。如果在任何旋转后的字符串与goal相等,则返回true。如果所有的旋转都不相等,最后返回false。

时间复杂度:

O(n^2)

空间复杂度:

O(n)

代码细节讲解

🦆
为什么在旋转字符串的比较中,需要从位置1开始旋转而不是从位置0开始?
在这个问题中,从位置0开始旋转实际上意味着不进行任何旋转,因为整个字符串会保持不变。这种情况已经在函数的一开始通过`if s == goal`进行了直接比较。因此,从位置1开始旋转是为了避免重复计算这种无变化的情况,直接从可能导致字符串内容改变的第一个旋转开始检查。
🦆
旋转操作的终止条件为什么是`range(len(s)-1)`而不是`range(len(s))`?是否有遗漏最后一种可能的旋转?
使用`range(len(s)-1)`是因为在旋转操作中,当`i`等于字符串的长度减1时,执行`s[i+1:]+s[:i+1]`将得到`s[:len(s)]`,即原字符串本身,这种旋转其实是无效的,相当于没有旋转。因此,实际的有效旋转只需要考虑到字符串长度减1的位置。
🦆
在比较`if s[i+1:]+s[:i+1] == goal`时,是否考虑了字符串`goal`比`s`长或短的情况,或者他们总是等长?
这个题解没有明确指出需要检查`s`和`goal`的长度是否相等,但从逻辑上讲,如果两个字符串长度不同,它们是不可能通过旋转变为相等的。因此,在实际应用中应当在比较之前加入长度相等的判断,以避免不必要的计算和可能的错误。
🦆
题解是否考虑了字符串中存在重复字符的情况,这是否会影响旋转后字符串的比较逻辑?
题解中的比较逻辑是基于字符串整体相等性的直接比较,对于重复字符的存在并不会产生影响。因为无论字符串中的字符如何重复,只要通过某种旋转能够使得两个字符串完全相等,该方法都能正确返回结果。因此,重复字符的存在不会影响旋转后字符串比较的逻辑。

相关问题