Finding the longest border of a string
Data Structures & Algorithms practice on Codemia
Step through 300 algorithm problems with animated visualisers that show the data structure changing as the code runs.
Introduction
A border of a string is a non-empty substring that is both a proper prefix and a proper suffix. Finding the longest border matters in pattern matching and repetition analysis because it tells you how much structure the string shares with itself.
Naive Idea First
The direct approach is to test every possible border length from longest to shortest. For a string s, you compare s[:k] with s[-k:] until you find the largest match.
That is easy to understand:
The problem is runtime. Comparing slices repeatedly can make this approach quadratic in the worst case.
The Efficient Approach: Prefix Function
The standard linear-time solution uses the prefix function from the Knuth-Morris-Pratt algorithm. For each position, the prefix function stores the length of the longest proper prefix that is also a suffix for the substring ending at that position.
Once you compute that array for the full string, the last value is exactly the length of the longest border of the whole string.
This runs in O(n) time and O(n) space.
Why the Prefix Function Works
Suppose the string is "abacaba". The longest border is "aba". The prefix-function array tracks how much prefix information survives as you scan left to right. When characters stop matching, the algorithm does not restart from zero blindly. Instead, it jumps to the next possible border length that was already computed.
That reuse of previously known borders is why KMP is fast. It avoids repeating work the naive approach would perform again and again.
Returning the Length Instead of the String
In many interview and competitive-programming problems, you only need the border length:
The actual border text is then s[:length].
Finding All Borders
The prefix-function array also lets you recover every border, not just the longest one. Starting from the final prefix value, repeatedly follow the prefix links:
This is a useful extension when the problem asks about repeated structure rather than only the maximum border.
Common Pitfalls
- Forgetting that a border must be proper, so the entire string does not count.
- Using repeated slicing in the naive approach and underestimating the performance cost.
- Confusing prefix function with suffix arrays or other unrelated string structures.
- Mishandling the empty-string case.
- Returning the border length when the problem expects the substring itself, or vice versa.
Summary
- A border is a substring that is both a proper prefix and a proper suffix.
- The naive approach is simple but can take quadratic time.
- The KMP prefix function gives the longest border in linear time.
- The last prefix-function value is the border length for the whole string.
- The same array can also be used to recover all borders, not just the longest one.
Related reading
- Finding the Longest Common Substring in a Large Data Set
- Finding the Longest Palindrome Subsequence with less memory
- Finding the longest repeated substring
- Finding the longest repeated substring without suffix arrays or suffix trees
- Finding the lowest unused unique id in a list
- Finding the median of an unsorted array
- Finding the minimum length RLE
- Finding the minimum number of swaps to convert one string to another, where the strings may have repeated characters

DSA Fundamentals
Master algorithmic patterns and data structures through hands-on LeetCode-style problems - from arrays and hashing to dynamic programming and advanced graphs.
View the courseTrack what you have practised
A free account saves your progress, solutions and study plan across every problem on Codemia.
Data Structures & Algorithms practice on Codemia
Step through 300 algorithm problems with animated visualisers that show the data structure changing as the code runs.