Lexicographical order
Sorting algorithms
Computational theory
String manipulation
Programming techniques

How to get the smallest in lexicographical order?

Data Structures & Algorithms practice on Codemia

Step through 300 algorithm problems with animated visualisers that show the data structure changing as the code runs.

Practice algorithms

Introduction

If you only need the smallest string in lexicographical order, you usually do not need to sort the entire collection. A single pass that keeps the current minimum is enough. The real detail to settle first is what “lexicographical” means in your program, because case sensitivity, locale rules, and normalization can change the result.

What Lexicographical Order Actually Means

Lexicographical order compares strings from left to right. The first position where two strings differ decides which string is smaller. If one string is a prefix of the other, the shorter string is usually considered smaller.

Examples:

  • 'app comes before apple'
  • 'apple comes before banana'
  • 'Zoo and zoo depend on the comparison rule your language uses'

That last example matters because many “unexpected” results are really comparison-policy issues rather than algorithm issues.

Use a Minimum Operation, Not a Full Sort

Sorting is O(n log n). Finding the minimum is O(n). If you want only one smallest element, scanning once is the right algorithmic choice.

In Python:

python
words = ["bat", "apple", "banana", "apricot"]
print(min(words))

In Java:

java
1import java.util.List;
2
3public class LexicographicalMin {
4    public static void main(String[] args) {
5        List<String> words = List.of("bat", "apple", "banana", "apricot");
6        String smallest = words.stream().min(String::compareTo).orElse("");
7        System.out.println(smallest);
8    }
9}

Both solutions express the real intent directly and avoid the extra cost of sorting.

Case Sensitivity Changes the Answer

Default string comparison often treats uppercase and lowercase differently. If your application wants case-insensitive lexicographical order, say so explicitly.

python
words = ["Zoo", "apple", "Banana"]
print(min(words))
print(min(words, key=str.lower))

The first result uses Python's default string ordering. The second compares using lowercase normalization. Those are different rules, so different answers are expected.

In Java, the equivalent idea is:

java
1import java.util.Comparator;
2import java.util.List;
3
4public class CaseInsensitiveMin {
5    public static void main(String[] args) {
6        List<String> words = List.of("Zoo", "apple", "Banana");
7        String smallest = words.stream()
8            .min(String.CASE_INSENSITIVE_ORDER)
9            .orElse("");
10        System.out.println(smallest);
11    }
12}

Locale-Aware Ordering Is a Different Problem

Raw language-library comparison is not always the same thing as human dictionary order in every language. If the strings are user-facing and multilingual, locale-aware comparison may be the real requirement.

In Java, Collator is the right tool for that class of problem:

java
1import java.text.Collator;
2import java.util.List;
3import java.util.Locale;
4
5public class LocaleMin {
6    public static void main(String[] args) {
7        Collator collator = Collator.getInstance(Locale.US);
8        List<String> words = List.of("éclair", "eagle", "zebra");
9        String smallest = words.stream().min(collator).orElse("");
10        System.out.println(smallest);
11    }
12}

This is not about performance anymore. It is about choosing the rule that matches user expectations.

If the Data Is Not Strings

Sometimes “lexicographically smallest” applies to sequences such as arrays, tuples, or lists. The comparison rule is still left-to-right, but now each position contains another comparable value.

For example, the lexicographically smallest list among several lists is the one whose first differing element is smaller. Python handles this naturally for lists of comparable items:

python
items = [[1, 4], [1, 3, 9], [2, 0]]
print(min(items))

The same reasoning applies: you only need a minimum scan, not a full sort, unless you actually need the entire order.

Define the Comparison Rule Up Front

A lot of bugs come from saying “smallest lexicographically” without defining:

  • case-sensitive or case-insensitive comparison
  • locale-aware or raw code-point comparison
  • normalization of accents or whitespace
  • exact strings or derived comparison keys

If you define those rules first, the implementation is usually trivial. If you skip that step, the implementation may be trivial but the result may still be wrong for the application.

Common Pitfalls

The most common mistake is sorting the entire collection when only the smallest element is needed. That is unnecessary work.

Another mistake is assuming raw string comparison matches human dictionary order in every language. It often does not.

Developers also forget that case sensitivity changes the answer. If the requirement is case-insensitive ordering, the comparison function must say so.

Summary

  • To find the lexicographically smallest item, scan for the minimum instead of sorting the whole collection.
  • Lexicographical comparison is left-to-right and prefix-sensitive.
  • Case sensitivity and locale rules can change the result.
  • Use built-in comparison tools such as min, String::compareTo, or locale-aware comparators.
  • Define the comparison rule first so “smallest” means the same thing everywhere in the code.

Related reading
Course
Intermediate
27 lessons
15 hours
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 course
Track 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.

Practice algorithms

All Rights Reserved.