`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 "".
Example 1:
Input: strs = ["flower","flow","flight"]
Output: "fl"
Example 2:
Input: strs = ["dog","racecar","car"]
Output: ""
Explanation: There is no common prefix among the input strings.
Constraints:
1 <= strs.length <= 200
0 <= strs[i].length <= 200
strs[i] consists of only lowercase English letters if it is non-empty.`
class Solution:
def longestCommonPrefix(self, strs: List[str]) -> str:
prefix = ""
for chars in zip(*strs):
if len(set(chars)) == 1:
prefix += chars[0]
else:
break
return prefix
🔍 How It Works
- zip(*strs)
This transposes the list of strings — it groups characters by their position.
For example:
strs = ["flower", "flow", "flight"]
list(zip(*strs))
Output: [('f','f','f'), ('l','l','l'), ('o','o','i'), ...]
set(chars)
Checks whether all characters in the current column are the same.If all characters match → add to prefix
Otherwise → break the loop.
:
🧩 for chars in zip(*strs):
This line means:
👉 "Go through each group of letters that are in the same position in all the words."
🎯 Example:
Suppose you have this list:
strs = ["cat", "car", "cap"]
Now let's look at the letters by position:
Position Word 1 Word 2 Word 3
0 c c c
1 a a a
2 t r p
So zip(*strs) will give the transpose
[('c', 'c', 'c'), ('a', 'a', 'a'), ('t', 'r', 'p')]
Then, when you write:
for chars in zip(*strs):
It’s like saying:
chars = ('c', 'c', 'c') → all letters at position 0
chars = ('a', 'a', 'a') → all letters at position 1
chars = ('t', 'r', 'p') → all letters at position 2
You loop through these letter groups one by one.
🤔 Why do this?
Because we want to find out if the same letter appears at the same position in all words.
If yes → it's part of the common prefix.
If not → we stop.
🔗 What is zip() used for in Python?
The zip() function is used to combine multiple lists (or other iterables) together, pairing items by their positions.
💡 Simple Example:
names = ["Alice", "Bob", "Charlie"]
ages = [25, 30, 35]
for pair in zip(names, ages):
print(pair)
🖨️ Output:
('Alice', 25)
('Bob', 30)
('Charlie', 35)
Each item from names is paired with the item at the same position in ages.
🧩 What does zip(*strs) do?
When you add the * in zip(*strs), you're telling Python:
“Take each string and treat its characters as separate items, then group characters by their positions.”
Example:
strs = ["dog", "doll", "door"]
zip(*strs)
🧠 Think of it like rotating the words so we can look column by column:
Word Characters
"dog" d
"doll" d
"door" d
➡️ zip(*strs) gives:
('d', 'd', 'd') ← All first letters
('o', 'o', 'o') ← All second letters
('g', 'l', 'o') ← All third letters (first mismatch)
✅ Summary
zip() → Combines items from multiple lists by position
zip(*strs) → Used to compare columns of characters from strings
It's very helpful when checking if words share the same starting letters
🎯 What are we trying to do?
We want to find the longest common prefix of a list of strings, like:
["flower", "flow", "flight"]
This means we want to compare the first letter of each word, then the second letter, then the third, etc., and stop as soon as there’s a mismatch.
⚙️ Why zip() is necessary here
Using zip(*strs) lets us compare all characters at the same position across all words:
Position Word 1 Word 2 Word 3
0 f f f
1 l l l
2 o o i ❌ mismatch!
zip(*strs) turns that into:
[('f', 'f', 'f'), ('l', 'l', 'l'), ('o', 'o', 'i'), ...]
With this, we can loop:
for chars in zip(*strs):
if all letters in chars are the same:
add to prefix
else:
break
✅ Why is it better than alternatives?
Without zip, you'd have to:
Loop through indices manually.
Do more error checking (like index out-of-range).
Write more complex, less readable code.
With zip(*strs), you get:
✔️ Simple
✔️ Pythonic
✔️ Automatically stops at the shortest word (since zip stops when any list runs out)
✔️ Easy to compare by positions
👨🏫 TL;DR
zip(*strs) is not just convenient, it’s the cleanest way to look at all strings character by character, in order — which is exactly what we need to find a common prefix.
:
✅ Use zip() when:
- You want to process items in parallel from multiple lists or strings
names = ['Alice', 'Bob']
scores = [85, 90]
for name, score in zip(names, scores):
print(name, score)
You need to pair corresponding elements from different sequences.
- You want to compare characters at the same position in multiple strings
python
Copy
Edit
strs = ['dog', 'dot', 'don']
for letters in zip(*strs):
print(letters)
Use zip(*strs) to align strings column-wise.
This is exactly what’s needed for problems like longest common prefix.
- You want to transpose rows to columns
matrix = [
[1, 2, 3],
[4, 5, 6],
]
transposed = list(zip(*matrix))
Output: [(1, 4), (2, 5), (3, 6)]
Think of it as rotating a grid.
❌ When NOT to use zip():
When you're processing a single list
When your sequences have different lengths and you care about the extras
When the order doesn’t matter
🧠 How to remember:
Ask yourself:
“Do I need to work with elements from multiple lists or strings at the same position?”
If YES → zip() is your friend.
🔹 Challenge 1: Pair students with their scores
python
Copy
Edit
students = ['Kavitha', 'Arun', 'Divya']
scores = [89, 92, 95]
Q: Do you need zip() here?
✅ Answer: Yes
Because you want to pair the first student with the first score, etc.
🔹 Challenge 2: Count how many times each word appears in a sentence
sentence = "apple orange apple banana orange apple"
words = sentence.split()
Q: Do you need zip()?
❌ Answer: No
You're only working with one list (words). Use a dictionary or collections.Counter.
🔹 Challenge 3: Compare characters at each position in a list of strings
words = ["flow", "flower", "flight"]
Q: Do you need zip()?
✅ Answer: Yes
Use zip(*words) to group letters by position.
🔹 Challenge 4: Calculate the difference between elements of two lists
python
Copy
Edit
a = [5, 9, 7]
b = [2, 3, 4]
Q: Do you need zip()?
✅ Answer: Yes
Because you want to subtract elements at the same index:
python
Copy
Edit
[5-2, 9-3, 7-4]
🔹 Challenge 5: Reverse a list
python
Copy
Edit
nums = [1, 2, 3, 4, 5]
Q: Do you need zip()?
❌ Answer: No
You just use slicing: nums[::-1]
🔹 Challenge 7: Combine three lists into tuples
python
Copy
Edit
a = [1, 2]
b = ['x', 'y']
c = ['apple', 'banana']
✅ Use zip
python
Copy
Edit
list(zip(a, b, c)) → [(1, 'x', 'apple'), (2, 'y', 'banana')]
Why? You’re aligning multiple sequences by index.
🔹 Challenge 8: Check if two strings are anagrams
python
Copy
Edit
s1 = "listen"
s2 = "silent"
❌ Don't use zip
Use sorted(s1) == sorted(s2) or a counter comparison. You don’t need index-wise pairing.
🔹 Challenge 9: Compare two lists element-wise for equality
python
Copy
Edit
a = [10, 20, 30]
b = [10, 25, 30]
✅ Use zip
python
Copy
Edit
for x, y in zip(a, b):
if x != y:
print(f"Mismatch: {x} ≠ {y}")
Why? You need index-aligned comparisons.
🎯 Challenge 10: Real Interview Scenario — Prefix Match
python
Copy
Edit
Given a list of product names:
products = ["macbook", "macpro", "macmini", "imac"]
Find the longest common prefix (used for auto-suggest dropdowns)
✅ Use zip
prefix = ""
for chars in zip(*products):
if len(set(chars)) == 1:
prefix += chars[0]
else:
break
⏱️ Time Complexity: O(S)
Where:
S is the sum of all characters across all strings.
In the worst case, we compare every character of every string until we hit a mismatch or exhaust the shortest string.
Let’s break it down:
zip(*strs) loops column by column (based on shortest string length): let’s say minLen = length of shortest string.
For each column, we check if all characters are the same:
That’s O(n) work, where n = number of strings.
So worst case = O(n * minLen) → which is linear in total characters, i.e., O(S).
📦 Space Complexity: O(1) (excluding output)
prefix is the only extra space we use — it stores the result, so it doesn’t count as extra unless specified.
set(chars) inside the loop creates a temporary set of up to n characters, so at most O(n) per iteration.
So overall: O(1) auxiliary space.
Total space = output string length + small temporary set = efficient.
✅ Summary:
Complexity Value
Time O(n * m) where n = number of strings, m = length of shortest string
Space O(1) auxiliary (excluding output string)