Algorithm

Longest Common Prefix

Arrays & Strings Pattern

Longest Common Prefix

Write a function to find the longest common prefix string amongst an array of strings. If there is no common prefix, return an empty string.

CONSTRAINTS
  • 1 <= strs.length <= 200
  • 0 <= strs[i].length <= 200
  • strs[i] consists of only lowercase English letters
EXAMPLE 1
Input: strs = ["flower","flow","flight"]
Output: "fl"
All three words share 'fl'. 'flower' and 'flow' share 'flo', but 'flight' diverges at position 2 with 'i'.
EXAMPLE 2
Input: strs = ["dog","racecar","car"]
Output: ""
There is no shared starting character among the three words, so the prefix is empty.
EXAMPLE 3
Input: strs = ["interview","internal","interpret"]
Output: "inter"
All three words share the prefix 'inter'. They diverge at position 5 with 'v', 'n', and 'p' respectively.
What if the array contains only one string?
The prefix of a single string is the string itself. There are no other strings to differ, so the entire string is the answer.
Can the prefix be longer than the shortest string in the array?
No. The prefix is bounded by the shortest string. If all other words share all its characters, the shortest string is the common prefix.
What if one of the strings is empty?
An empty string has no characters, so there is no common prefix. Return empty string immediately.
Does the order of strings in the array matter?
No. The common prefix must be shared by all strings, regardless of their order.

The longest common prefix is the longest run of characters that every word in the array shares, starting from position 0. The instant even one word disagrees — or simply runs out of letters — the shared prefix ends there. We return that shared run as a string, or the empty string "" when the words share nothing at the start. One bound is worth noticing immediately: the answer can never be longer than the shortest word in the array, because that word runs out of characters first.

The honest first idea: shrink a candidate word by word

Take the first word and treat it as a guess for the whole prefix. Compare it against the second word: if the second word does not start with the guess, chop the last character off the guess and try again, repeating until the second word does start with it. That shortened guess is now the common prefix of the first two words. Carry it forward and repeat against the third word, the fourth, and so on; if the guess ever shrinks to empty, no prefix exists and we stop.

python
if not strs:
    return ""
prefix = strs[0]
for i in range(1, len(strs)):
    while not strs[i].startswith(prefix):
        prefix = prefix[:-1]
        if not prefix:
            return ""
return prefix

This works, but look at the wasted motion. We begin by assuming the entire first word is the prefix — possibly 200 characters — and discover how wrong we are only by peeling it back one character at a time, re-scanning from the front on each startswith check. If the true prefix is short but the first word is long, we compare deep into characters that were never going to matter. The work is driven by the first word's length, when it ought to be driven by how quickly the words start to disagree.

The reframe: read the words in columns, not in rows

Stack the words on top of each other and read down the columns instead of across the rows. Column 0 is the first character of every word; column 1 is the second character of every word; and so on. A common prefix is exactly the run of columns in which all the letters agree. The moment one column holds a disagreement — or one word has no letter in that column at all — the prefix is everything in the columns before it. Framed this way, the answer reveals itself the instant the first disagreement appears, and we never read a single character past the point where the words split.

Scanning column by column

Use the first word to supply the letters to check, position by position. At each position i, look at that same position in every other word. If all of them have the same character there, the prefix extends by one. If any word differs, or any word is too short to have a character at position i, stop and return everything matched so far.

python
if not strs:
    return ""
for i in range(len(strs[0])):
    char = strs[0][i]
    for j in range(1, len(strs)):
        # word ran out, or the character differs
        if i == len(strs[j]) or strs[j][i] != char:
            return strs[0][:i]
return strs[0]
Crucial Notethe two halves of the stopping test — i == len(strs[j]) before strs[j][i] != char — must be checked in that order, and both are load-bearing. A word can simply end while the others continue: for ["ab", "a"] the answer is "a", and at column 1 the second word has no character at all. Checking i == len(strs[j]) first catches that and returns "a"; skip it and try strs[j][1] and you index past the end of the string and crash. Short-circuiting on length before touching the character is what keeps the column scan safe.
Worked Example:strs = ["flower", "flow", "flight"]
The guide word is "flower". We check each column across all three words:
- Column 0: 'f' in "flower", "flow", "flight" — all agree. Prefix so far: "f".
- Column 1: 'l' in all three — agree. Prefix so far: "fl".
- Column 2: guide has 'o'; "flow" has 'o' (agree), but "flight" has 'i' — disagreement. Stop and return the columns before this one: "fl".

Now a case with no shared start — strs = ["dog", "racecar", "car"]:
- Column 0: guide "dog" has 'd', but "racecar" has 'r' — they disagree at the very first column. Return strs[0][:0], the empty string "". No word past the first even needs a second character read.

What we paid, and what we bought

Both approaches are linear in the worst case, but they are driven by different things. The column scan stops at the first disagreement, so it reads at most (length of the answer + 1) characters from each of the N words — its cost is bounded by the answer's length times the number of words, never by how long the first word happens to be. When words diverge early (the common case), it barely reads anything. The shrink-the-guess approach, by contrast, can be dragged out by a long first word regardless of how short the real prefix is. The lesson generalizes past this one problem: when a question asks you to compare many sequences at the same positions — a shared prefix, a first point of divergence, a per-column vote — think about reading down the columns and stopping at the first disagreement, rather than processing each sequence whole. And carry the two guard rails from the Crucial Note onto any column scan: a sequence can end early, and the order in which you test "ended" versus "differs" decides whether the code is correct or crashes.

Interactive Strategy Visualization

Vertical Scanning

Column-by-Column Consensus Engine
Scanning column0
STR0
F
L
O
W
E
R
STR1
F
L
O
W
STR2
F
L
I
G
H
T
Prefix so far""
📡

Column 0: reference character is 'F' from "FLOWER".

O(S) Horizontal Shrink
O(answer × N) Column Scan · Early Exit