Back to Python & Coding

PYTHON & CODING · QUESTION 08

How do you find duplicate characters in a string in Python?

On this page
Intermediate 6 min read
Interview-ready answerThe concise version to remember

Scan the string once while storing characters already seen in a set. If the current character is already present, the string contains a duplicate; otherwise add it and continue. This takes O(n) expected time and O(k) extra space, where n is the string length and k is the number of distinct characters. Clarify whether comparison is case-sensitive and whether spaces count.

LET'S MAKE IT SIMPLE

First, the idea in plain English

The direct approach compares each character with the others, but that repeats work. A set remembers which characters have appeared so far. As you scan from left to right, each lookup answers “have I seen this before?” If yes, stop; if no, record it. This is a common interview example of using a data structure to trade some memory for faster checking.

FOLLOW THE JOURNEY

Track the seen set as the string is scanned

Show how one set lookup per character detects the first repeated character.

Track the seen set as the string is scannedShow how one set lookup per character detects the first repeated character.Execution trace
01bNot seen → add {b}
02aNot seen → add {b, a}
03nNot seen → add {b, a, n}
04aAlready present → duplicate

This trace stops at the first duplicate. If all duplicates are needed, count occurrences or collect repeated values instead.

For the string banana, b and a are added, n is added, then the next a is already in the seen set, so a duplicate is found.

How to read this visual
This trace stops at the first duplicate. If all duplicates are needed, count occurrences or collect repeated values instead.

UNDER THE HOOD

How it works, step by step

01

Start with an empty set

Create a set that will hold characters encountered so far.

Why it matters: Membership checks express whether a character has appeared.

02

Read one character

For each character, check whether it is already in the set.

Why it matters: This processes the input in a single pass.

03

Return or record

If present, return true; otherwise add it and continue.

Why it matters: The first repeat is enough to answer whether any duplicate exists.

04

Finish without a repeat

If the loop ends, return false.

Why it matters: Every character was unique under the chosen comparison rules.

OUTSIDE THE TEXTBOOK

A practical example

For “banana”, the scan records b, a, and n. The next a is already recorded, so the function can stop immediately. For “lamp”, each character is new, so it reaches the end and returns false.

GO A LITTLE DEEPER

Technical details that matter

  • Let n be the number of characters and k the number of unique characters seen before stopping. The loop performs at most n hash lookups and insertions, giving expected O(n) time and O(k) additional space.
  • Strings are Unicode sequences. Whether visually similar characters count as duplicates can require normalization, and case folding is a separate product decision.
  • The set solution answers whether any repeated character exists; returning all duplicates or their frequencies is a different output requirement.
Python example
def has_duplicate_characters(text: str) -> bool:\n    seen: set[str] = set()\n    for character in text:\n        if character in seen:\n            return True\n        seen.add(character)\n    return False\n\nprint(has_duplicate_characters("banana"))  # True\nprint(has_duplicate_characters("lamp"))    # False

Each character is checked before it is added. The function returns early on the first repeated character; an empty string returns false. This code is case-sensitive and treats spaces as characters.

MAKE A GOOD CHOICE

When is this useful?

  • Use a set when the requirement is only to detect whether any duplicate exists.
  • Use a frequency dictionary when counts or all repeated characters are required.
  • Normalize text first only if the requirements say that case or Unicode variants should compare as equal.

WATCH OUT FOR

Common misunderstandings

  • Comparing characters without clarifying case and whitespace rules.
  • Claiming worst-case O(1) hashing without the expected-case qualifier.
  • Building a set first and comparing lengths when early exit could avoid processing the rest.

REAL-WORLD TRADE-OFFS

Limitations and failure cases

  • The set uses memory proportional to unique characters seen.
  • Case-sensitive comparison treats A and a as different.
  • Unicode normalization may be needed for some visually identical text.

WHAT TO REMEMBER

Key takeaways

  1. 1A set supports efficient seen-before checks.
  2. 2The scan is expected O(n) time and O(k) extra space.
  3. 3State comparison rules explicitly.
  4. 4Use a frequency map if counts are required.

PRACTICE THE FOLLOW-UP

What might an interviewer ask next?

How would you return all repeated characters?

Track counts in a dictionary, then return keys whose count exceeds one. Define whether each character should appear once or alongside its count.

What are the complexities?

Expected O(n) time with hashing and O(k) space for k distinct characters visited; the function may exit early.

How would you make the check case-insensitive?

Normalize or case-fold the input according to the requirements, then scan the normalized string. Unicode text may need additional normalization decisions.

SAY IT OUT LOUD

How to explain this in an interview

“I would scan the string once and maintain a set of characters already seen. For each character, I check membership; if it is present, I return true, otherwise I add it. If the scan finishes, there are no duplicates. This is expected O(n) time and O(k) extra space. I would clarify case sensitivity and whether spaces or Unicode-equivalent characters should count as duplicates.”

Continue your learning path

Connect this question to the roadmap topic it supports.

Open roadmap topic