ctci/01. Arrays and strings/1.9. string_rotation.md

1.3 KiB

1.9. String rotation

Given s1 and s2, calculate if s2 is a rotation of s1 using only one call to isSubstring, a function that checks if a string is a substring of another

example: 'waterbottle' is a rotation of 'erbottlewat'

First idea

Need to have the same lengths and same count of characters.

from collections import Counter
if len(s1) != len(s2) or Counter(s1) != Counter(s2):
    return 0
if len(s1) < 3 or s1 == s2:
    return 1

Find s1[0] in s2, index i. Check that s2, from i to the end is equal to the substring of s1, and same with the first part.

indexes = [i for i, e in enumerate(s2) if e == s1[0]]
for idx in indexes:
    offset = len(s1) - idx
    if s2[idx:] == s1[:offset] and s2[:idx] == s1[offset:]:
        return 1
return 0

Finds all occurences of s1[0] in s2, checks if 'wat' == 'wat', and then 'erbottle' == 'erbottle'. Takes O(n) time, O(1) space. No calls to isSubstring, either 2 calls or none. I don't see the point of just one.

Hints and solution

Let s1 be divided into two parts, x and y. s1 = xy and s2 = yx. If we concatenate s2 with itself, s2 = yxxy. In which case s1 is a substring of s2s2. But this takes O(n) time in isSubstring and O(n) space.

return isSubstring(s1, s2 + s2)