Check If One String Is a Rotation of Another

Solve this Problem
Easy10–15 min
Topics
Companies
Given two strings s and goal, return true if and only if s can become goal after some number of left rotations — repeatedly moving characters from the front of the string to the back (e.g. rotating "abcde" by 2 gives "cdeab"). Trying every rotation offset and rebuilding the string each time works, but it's wasteful. The key trick: every rotation of s is guaranteed to appear as a contiguous substringSubstringA contiguous run of characters taken from within a larger string — unlike a subsequence, the characters must be adjacent and in order. somewhere inside s + s. So the whole problem reduces to one substring-containment check on the doubled string.

Test Case 1:

Input:s = "abcde", goal = "cdeab"
Output:true
Explanation:Shifting the first 2 characters of s to the back turns "abcde" into "cdeab".

Test Case 2:

Input:s = "abcde", goal = "abced"
Output:false
Explanation:Same letters, but no rotation of "abcde" produces "abced" — order matters, this isn't an anagram check.

Test Case 3:

Input:s = "a", goal = "a"
Output:true
Explanation:A shift of 0 is a valid rotation — the string rotated by nothing is itself.

Constraints

  • 1 ≤ s.length, goal.length ≤ 10⁴
  • s and goal consist of lowercase English letters
🚀

Try the Dry Run

Don't just read the solution — watch it execute, one step at a time.

🧪Try your own test case
1class Solution {
2 public boolean isRotation(String s, String goal) {
3 if (s.length() != goal.length()) return false;
4 String doubled = s + s;
5 return doubled.contains(goal);
6 }
7}
8
String
a
b
c
d
e
String
c
d
e
a
b
Variables
s.length5
goal.length5
COMPARE

s and goal both have length 5 — lengths match, so a rotation is at least possible.

Step 1 / 3

Approach & Solutions

Brute Force — Try Every Rotation Offset

Brute

If the lengths differ, s can never rotate into goal. Otherwise, for every possible shift from 0 to n-1, physically build that rotation of s (slice and concatenate) and compare it to goal. Correct, but building a fresh n-length string for every one of the n shifts adds up.

TimeO(n²)
SpaceO(n)
1class Solution { 2 public boolean isRotation(String s, String goal) { 3 if (s.length() != goal.length()) return false; 4 int n = s.length(); 5 for (int shift = 0; shift < n; shift++) { 6 String rotated = s.substring(shift) + s.substring(0, shift); 7 if (rotated.equals(goal)) return true; 8 } 9 return false; 10 } 11}

Optimal — Concatenation Trick

Optimal

Every rotation of s is guaranteed to appear as a contiguous substring somewhere inside s + s — concatenating s with itself. So after checking the lengths match, the whole problem collapses into one substring-containment check: does s + s contain goal?

TimeO(n)
SpaceO(n)
1class Solution { 2 public boolean isRotation(String s, String goal) { 3 if (s.length() != goal.length()) return false; 4 String doubled = s + s; 5 return doubled.contains(goal); 6 } 7}

Related Problems