S1Q2 · Check String Rotation¶
⚡ Quick Reference
Function: is_rotation(str1: str, str2: str) -> bool
Core idea: if str2 is a rotation of str1, it will always appear as a substring of str1 + str1.
def is_rotation(str1: str, str2: str) -> bool:
if len(str1) != len(str2):
return False
return str2 in str1 + str1
Key rules:
- Both strings must have the same length - else not a rotation
- str2 in (str1 + str1) checks if str2 is any rotation of str1
- Same string (str1 == str2) counts as a rotation (shift by 0)
Problem Statement¶
Problem
Write a function is_rotation(str1, str2) that returns True if str2 is a rotation of str1.
Examples:
str1="abcde", str2="cdeab"
True
str1="hello", str2="ehllo"
False
str1="hello", str2="helol"
False
Understanding the trick¶
Concatenating str1 with itself contains every possible rotation of str1 as a contiguous substring:
str1 = "apple"
str1 + str1 = "appleapple"
Rotations visible inside "appleapple":
a[pplea]pple → "pplea"
ap[pleap]ple → "pleap"
app[leapp]le → "leapp"
appl[eappl]e → "eappl"
apple[apple] → "apple"
So checking str2 in str1 + str1 checks all 5 rotations in one step.
Why the length check matters
Without it, "ab" in "abcabc" would return True even though "ab" is not a rotation of "abc" - it's a different-length string that just happens to appear as a substring. Always check len(str1) == len(str2) first.
Tracing all examples¶
str1 |
str2 |
Lengths equal? | str1+str1 |
str2 in ... |
Result |
|---|---|---|---|---|---|
"abcde" |
"cdeab" |
✅ (5=5) | "abcdeabcde" |
✅ | True |
"hello" |
"ehllo" |
✅ (5=5) | "hellohello" |
❌ | False |
"hello" |
"helol" |
✅ (5=5) | "hellohello" |
❌ | False |
Solution approaches¶
def is_rotation(str1: str, str2: str) -> bool:
if len(str1) != len(str2):
return False
n = len(str1)
for i in range(n):
rotation = str1[i:] + str1[:i]
if rotation == str2:
return True
return False
Generates each rotation explicitly and compares. O(n²) vs O(n) for the in approach, but shows clearly what a rotation is.
Key takeaways¶
str2 in str1+str1 - elegant O(n) trick
Concatenating a string with itself contains every rotation as a contiguous substring. Python's in operator runs an efficient substring search - one line replaces an entire loop over rotations.
Length check is mandatory
Two strings of different lengths can never be rotations of each other. Without the length check, shorter strings would incorrectly match as substrings of the doubled string.
Anagram ≠ Rotation
"ehllo" is an anagram of "hello" (same letters) but not a rotation (order matters). Rotations preserve the original sequence - only the starting point shifts.