🏷️ Category:Β Lists / HashSet Β |Β  🎯 Difficulty:Β EasyΒ Β |Β  πŸ”₯Β Frequency:Β β˜…β˜…β˜…β˜…β˜†


πŸ“‹ Problem Statement

Given a list of integers, return all elements that appear more than once. This problem is crucial to understand how to Find All Duplicates in a List.

πŸ“₯ Input  β†’ [1, 2, 3, 2, 4, 3, 5]
πŸ“€ Output β†’ [2, 3]

πŸ“₯ Input  β†’ [4, 3, 2, 7, 8, 2, 3, 1]
πŸ“€ Output β†’ [2, 3]

πŸ“₯ Input  β†’ [1, 2, 3]
πŸ“€ Output β†’ []

🧠 What the Interviewer is Testing

ConceptWhy It Matters
Set for O(1) lookupEfficient membership testing
Tracking seen vs duplicatesTwo-set pattern
Edge casesEmpty list, all unique

πŸ’‘ Approach

Use TWO sets:
  seen      β†’ elements we have already encountered
  duplicates β†’ elements seen more than once

For each number:
  If it's in 'seen' β†’ add to 'duplicates'
  Else β†’ add to 'seen'

βœ… Optimal Solution

def find_duplicates(nums: list) -> list:
    seen = set()
    duplicates = set()

    for num in nums:
        if num in seen:
            duplicates.add(num)
        else:
            seen.add(num)

    return list(duplicates)

# ── Test Cases ─────────────────────────────────
print(find_duplicates([1, 2, 3, 2, 4, 3, 5]))    # βœ… [2, 3]
print(find_duplicates([4, 3, 2, 7, 8, 2, 3, 1])) # βœ… [2, 3]
print(find_duplicates([1, 2, 3]))                  # βœ… []
print(find_duplicates([]))                         # βœ… []

πŸ”„ Alternative Using Counter

from collections import Counter

def find_duplicates_counter(nums: list) -> list:
    return [num for num, count in Counter(nums).items() if count > 1]

πŸ’¬ Pro tip: Mention Counter as an alternative β€” it’s cleaner and shows library knowledge.

πŸ’¬ Pro tip: Mention Counter as an alternative β€” it’s cleaner and shows library knowledge.


πŸ“Š Complexity Analysis

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ Time  O(n)  β”‚ Single pass through the list       β”‚
β”‚ Space O(n)  β”‚ Two sets in worst case             β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

🎀 How to Explain in the Interview

β€œI use two sets β€” one to track all seen elements, another to collect duplicates. As I iterate, if a number is already in β€˜seen’, it goes into β€˜duplicates’. This is O(n) time with O(n) space. Alternatively, Counter from collections gives a clean one-liner.”

β€œI use two sets β€” one to track all seen elements, another to collect duplicates. As I iterate, if a number is already in β€˜seen’, it goes into β€˜duplicates’. This is O(n) time with O(n) space. Alternatively, Counter from collections gives a clean one-liner.”


πŸ” Common Follow-up Questions

Q1 β†’ Return count of each duplicate?

from collections import Counter
def duplicate_counts(nums):
    return {k: v for k, v in Counter(nums).items() if v > 1}
# {2: 2, 3: 2}

Q2 β†’ In-place without extra space?

# Only works if nums contains 1 to n (mark visited by negating)
def find_duplicates_inplace(nums):
    result = []
    for num in nums:
        idx = abs(num) - 1
        if nums[idx] < 0:
            result.append(abs(num))
        else:
            nums[idx] *= -1
    return result

πŸ“ Set 1 of 4 β€” Python Interview Prep Series β€” devprepguide.com

Scroll to Top