How to find the lexicographically smallest string by reversing a substring?
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Introduction
In the realm of string manipulation, one interesting problem is finding the lexicographically smallest string by reversing exactly one contiguous substring. This problem has applications in genetic data analysis, text processing, and competitive programming. The goal is to determine the smallest possible string achievable through a single reversal operation.
Understanding Lexicographical Order
Lexicographical order is the generalization of dictionary order to strings. Given two strings s1 and s2, s1 is lexicographically smaller than s2 if, at the first position where they differ, the character in s1 comes before the character in s2 alphabetically.
For example:
- "abc" is smaller than "abd" (differ at position 2: 'c' < 'd')
- "a" is smaller than "aa" (first string is a prefix, and shorter)
Problem Statement
Given a string, find the smallest possible string by reversing exactly one of its substrings. A substring is a contiguous sequence of characters. Note that reversing a substring of length 1 (or length 0) effectively means "no change," so the original string is always a valid candidate.
Brute Force Solution
The straightforward approach considers all possible substrings:
- For each pair of indices where , reverse the substring from index to .
- Compare the resulting string with the current minimum.
- Return the smallest string found.
Complexity
- Time: , because there are pairs and each string comparison/reversal takes .
- Space: for storing the reversed string.
Optimized Approach
The brute force is impractical for large strings. A key observation enables a much faster solution:
Observation: To minimize the string lexicographically, you want the smallest possible character as early as possible. The optimal reversal must bring a smaller character to an earlier position.
Greedy Algorithm
- Scan left to right. Find the first position where is not the smallest character in .
- Find the rightmost occurrence of the smallest character in . Call this position .
- Reverse .
This works because the reversal brings the smallest available character to the earliest "imperfect" position, and taking the rightmost occurrence ensures that if there are ties, the characters between and are sorted in the best possible order after reversal.
This runs in for finding the optimal reversal point, plus for the reversal itself, giving overall.
Worked Example
Original string: "cab"
Brute force enumeration:
| Indices | Original Substring | Reversed | Resulting String | Smaller than "cab"? |
| (0, 1) | "ca" | "ac" | "acb" | Yes |
| (0, 2) | "cab" | "bac" | "bac" | Yes |
| (1, 2) | "ab" | "ba" | "cba" | No |
The smallest result is "acb", achieved by reversing indices (0, 1).
Greedy approach: At position 0, the smallest character in "cab" is 'a' at index 1. Reverse s[0..1] to get "acb". Same answer, found in one scan.
Edge Cases
- Already sorted: If the string is already the lexicographically smallest (e.g., "abc"), no reversal improves it.
- All identical characters: Any reversal produces the same string, so the original is returned.
- Single character: The string is already minimal.
Summary
| Approach | Time Complexity | Space Complexity | Practical for |
| Brute force | Small strings (n < 1000) | ||
| Greedy | Any string length |
Finding the lexicographically smallest string by reversing a substring comes down to identifying where the string first deviates from sorted order and reversing just enough to bring the smallest available character forward. The greedy approach achieves this in linear time, making it practical for large inputs.

