First, compute the suffix array of the string. Then compute the longest common prefix array (this can also be done in linear time). That is, for all i, LCP[i] is the length of the longest common prefix of the ith smallest suffix and the (i+1)th smallest suffix.
Let S be the longest substring that is repeated without overlapping, and let l be the length of S. S may occur a few times in the string; let's say lo is the first index at which it appears, and hi is the last index. It must be the case that hi - lo is at least the length of S (otherwise the occurrences would overlap).
The suffix starting at position lo and the suffix starting at position hi have a common prefix whose length is at least that of S. That means that if i is the lexicographical rank of the suffix starting at position lo, and j is the lexicographical rank of the suffix starting at position hi, and i is less than j, then the values LCP[i], LCP[i+1], ..., LCP[j-1] are all greater than or equal to l. If j is less than i, then LCP[j], LCP[j+1], ..., LCP[i-1] are all greater than or equal to l.
In other words a repeated substring of length l is always associated with a subarray (that is, a set of consecutive elements) in the LCP array that are all greater than or equal to l.
So what we will do is consider all "maximal rectangles" inside the LCP array. Suppose we have a subarray of the LCP array, where the minimum value in that subarray is m. This subarray represents a set of suffixes of the original string that all start with the same m characters. In order to find a pair of such suffixes that are as far apart from each other as possible (i.e., have as long a common prefix as possible without overlapping) we will surely want this subarray to be as large as possible. So we extend it to the left and to the right as much as possible. A "maximal rectangle" is a subarray that can't be extended any further. So for example, in the array {2, 3, 2, 1, 4}, the subarray {2, 3, 2} is maximal because it can't be extended to the left, and if it were extended to the right then it would contain 1, which is smaller than the current minimum element.
To find all maximal rectangles in the LCP array is equivalent to finding the all nearest smaller values (ANSV) on both sides. This is because every maximal rectangle has some smallest element (possibly not unique) and that smallest element is the one that restricts whether the rectangle can be extended to the left or to the right: namely, you can't extend it in one direction any further once you encounter an element that's smaller than the smallest element.
Now recall that if you have a rectangle LCP[i], LCP[i+1], ..., LCP[j-1] whose minimum value is m, then it represents a set of suffixes that start at indices SA[i], SA[i+1], ..., SA[j] (where SA is the suffix array) and have a common prefix of length m. Let d be the difference between the minimum of these SA values and the maximum. If d is greater than or equal to m, then it means there are two substrings of length m that are equal and whose starting points are at least d apart, and since d is greater than m, they're disjoint. If d is less than m, then we can only find two equal disjoint substrings of length d, not m: if we were to extend them any further to the right, then they would overlap. So the best disjoint repeating substring length we can get from a given maximal rectangle is the minimum of its d and m values. By taking the maximum over all maximal rectangles we get the answer to the original problem.
If you compute all the maximal rectangles as the first step, you will find yourself then having to compute a bunch of range minimum queries to get the minimum and maximum SA values for each rectangle. This will typically make your solution O(n log n). However, with a modification to the stack-based ANSV algorithm we can also compute the minimum and maximum SA values as part of the linear-time ANSV computation, giving an overall linear time algorithm.
To wit, consider a pair of arrays A and B, each with n elements. We want to produce the following output:
- N, the "nearest smaller index on the left" array, that is, for each i, N[i] is the largest j such that A[j] is strictly less than A[i]
- M, where M[i] is the minimum of B[N[i]], B[N[i]+1], ..., B[i]
The regular ANSV problem only asks to compute N, which we do by keeping a stack of indices, and when we process A[i], we pop off all indices j_1, ..., j_m from the stack such that A[j_1], ..., A[j_m] are greater than or equal to A[i], before pushing i on to the stack. In the modified version, we can compute M as well using the formula M[i] = min(B[i], M[j_1], ..., M[j_m]).
In the original problem we have to scan in both directions, and in each scan we have to compute both the range minimum and the range maximum.