AlgoMaster Logo

Rotate String

Last Updated: March 31, 2026

easy

Understanding the Problem

We need to determine if one string is a rotation of another. A rotation means taking some number of characters from the front of the string and moving them to the back. For example, "cdeab" is a rotation of "abcde" because we moved the first two characters ("ab") to the end.

The first thing to notice: if s and goal have different lengths, the answer is immediately false. You can't rotate a string into a string of a different length. So that's our quick early exit.

The real question is: given two strings of the same length, how do we efficiently check if one is a rotation of the other?

Key Constraints:

  • 1 <= s.length, goal.length <= 100 — With n up to 100, even O(n^3) would be fine. This problem is not about optimizing runtime. It's about recognizing a clean, elegant approach.
  • s and goal consist of lowercase English letters. — No special characters or unicode to worry about. Simple character comparison works.

Approach 1: Brute Force (Try All Rotations)

Intuition

The most direct approach: try every possible rotation of s and check if any of them equals goal. Since a string of length n has exactly n distinct rotations (including the original), we generate each one and compare.

To generate the k-th rotation, we take the substring from index k to the end and append the substring from index 0 to k. For "abcde" with k=2, that gives us "cde" + "ab" = "cdeab".

Algorithm

  1. If s and goal have different lengths, return false.
  2. For each rotation amount k from 0 to n - 1:
    • Build the rotated string: s[k..n-1] + s[0..k-1].
    • If this equals goal, return true.
  3. If no rotation matches, return false.

Example Walkthrough

1k=0: rotation = "abcde", compare with goal "cdeab"
0
a
rotation k=0
1
b
rotation k=0
2
c
rotation k=0
3
d
rotation k=0
4
e
rotation k=0
1/6
0
c
goal
1
d
goal
2
e
goal
3
a
goal
4
b
goal
1/6

Code

This works but rebuilds the entire string for every rotation. Is there a way to check all rotations at once without constructing each one?

Approach 2: Concatenation Trick

Intuition

If you concatenate s with itself, every possible rotation of s appears as a contiguous substring inside s + s. For s = "abcde", s + s = "abcdeabcde" contains all five rotations as length-5 windows. So the question becomes: is goal a substring of s + s?

Algorithm

  1. If s and goal have different lengths, return false.
  2. Concatenate s with itself to get doubled.
  3. Check if goal is a substring of doubled.
  4. If yes, return true. Otherwise, return false.

Example Walkthrough

1Step 1: Concatenate s with itself → "abcdeabcde"
0
a
first copy
1
b
first copy
2
c
first copy
3
d
first copy
4
e
first copy
5
a
second copy
6
b
second copy
7
c
second copy
8
d
second copy
9
e
second copy
1/6
0
c
goal
1
d
goal
2
e
goal
3
a
goal
4
b
goal
1/6

Code

The concatenation trick is elegant, but it creates a new string of length 2n. Can we check the rotation property without allocating any extra strings?

Approach 3: Direct Character Comparison

Intuition

For each possible starting position k in s, we check if the characters of s starting at k (wrapping around using modular arithmetic) match goal character by character. Instead of building s.substring(k) + s.substring(0, k), we use s.charAt((k + j) % n) to access the j-th character of the k-th rotation directly.

Algorithm

  1. If s and goal have different lengths, return false.
  2. For each starting offset k from 0 to n - 1:
    • Compare each character: check if s[(k + j) % n] == goal[j] for all j from 0 to n - 1.
    • If all characters match, return true.
  3. If no offset works, return false.

Example Walkthrough

1k=0: s[(0+0)%5]='a' vs goal[0]='c' → mismatch, skip
0
a
(k+j)%n=0
1
b
2
c
3
d
4
e
1/8
0
c
j=0
1
d
2
e
3
a
4
b
1/8

Code