2
s = raw_input()
n = len(s)
el = []
z = n - 1
while z >= 0:
    x = s[z:] + s[:z]
    z = z - 1
    el.append(x)
print max(el)

The code is working fine but it is very inefficient.
Is there a more time efficient method to solve the problem?

greybeard
  • 2,249
  • 8
  • 30
  • 66

1 Answers1

0

Approach

You can solve this in linear time using suffix arrays. Given the input string s, construct the doubled string ss. Use a linear-time algorithm to construct the suffix array of ss. The suffix array holds the indices of the suffices of ss in lexicographic order. Finally, scan backwards through the suffix array, skipping over the indices that are in the second half of ss. The lexicographically largest suffix starting in the first half of ss can then be trimmed to a rotation of s.

The problem is similar to the problem described here, except that problem is about the lexicographically smallest rotation, and you want the lexicographically largest rotation.

Implementation

The article linked above mentions some of the algorithms you could use for the suffix array construction. I will not give an explicit construction for this part here, but for a Python implementation, see for example this article.

So assuming you have some implementation of a suffix array algorithm create_suffix_array(s: str) -> [int], such that create_suffix_array(s) returns the index sequence of the suffices in lexicographic order, you can then apply the algorithm to your problem like this:

def rotate(s: str, n: int) -> str:
  return s[n:] + s[:n]

def solve(s: str) -> str:
  indices: [int] = create_suffix_array(s + s)

  is_first_half = lambda i: i < len(s)

  best_index = next(filter(is_first_half, reversed(indices)))

  return rotate(s, best_index)

Correctness of the algorithm

Let s be a string of length n. Let i be the index of the lexicographically largest suffix of ss that is starting in the first half of ss. The suffix of ss that is defined by i is s[i,n-1]s.

Consider any j in [0,n-1]. Then the suffix of ss that is defined by j cannot be larger than s[i,n-1]s. So s[j,n-1]s <= s[i,n-1]s. Then it follows that any two equal-sized prefixes of these suffices have the same ordering. In particular, s[j,n-1]s[0,j-1] <= s[i,n-1]s[0,i-1], since both are n-sized prefixes of the two suffices.

Therefore, s[i,n-1]s[0,i-1] is the lexicographically largest rotation of s.