Medium

Longest Repeating SubstringPython

Full explanation · Time O(nlogn) · Space O(n)

# Time:  O(nlogn)
# Space: O(n)

import collections


class Solution(object):
    def longestRepeatingSubstring(self, S):
        """
        :type S: str
        :rtype: int
        """
        M = 10**9+7
        D = 26

        def check(S, L):
            p = pow(D, L, M)
            curr = reduce(lambda x, y: (D*x+ord(y)-ord('a')) % M, S[:L], 0)
            lookup = collections.defaultdict(list)
            lookup[curr].append(L-1)
            result = 0
            for i in xrange(L, len(S)):
                curr = ((D*curr) % M + ord(S[i])-ord('a') -
                        ((ord(S[i-L])-ord('a'))*p) % M) % M
                if curr in lookup:
                    for j in lookup[curr]:
                        if S[j-L+1:j+1] == S[i-L+1:i+1]:
                            if result == 0:
                                result = i
                            return result-L+1
                lookup[curr].append(i)
            return result

        left, right = 0, len(S)-1
        while left <= right:
            mid = left + (right-left)//2
            if not check(S, mid):
                right = mid-1
            else:
                left = mid+1
        return right