StackScholar
  • System Design Interview Preparation

    Beginner to advanced, with interactive simulators and full design case studies.

  • Python Full-Stack Interview Preparation

    Master backend + frontend questions with real-world cases.

  • AI/ML Engineer Interview Preparation

    ML, deep learning, LLMs, RAG, MLOps and system design - with mock interviews.

Rapid Review CSnewDSA VisualizerReviewBlog
Search⌘K
System Design Interview PreparationPython Full-Stack Interview PreparationAI/ML Engineer Interview Preparation
Rapid Review CSnewDSA VisualizerReviewBlog
CurriculumAll questionsFlashcardsGlossaryVisualizersDSA Visualizer

Navigate by Range

  • Q&A Python-1-5
  • Q&A Python-6-10
  • Q&A Python-11-15
  • Q&A Python-16-20
  • Q&A Python-21-25
  • Q&A Python-26-30
  • Q&A Python-31-35
  • Q&A Python-36-40
  • Q&A Python-41-45
  • Q&A Python-46-50
  • Q&A Python-51-55
  • Q&A Python-56-60
  • Q&A Python-61-65
  • Q&A Python-66-70
  • Q&A Python-71-75
  • Q&A Python-76-80
  • Q&A Python-81-85
  • Q&A Python-86-90
  • Q&A DB-MySQL-1-5
  • Q&A DB-MySQL-6-10
  • Q&A DB-MySQL-11-15
  • Q&A DB-MySQL-16-20
  • Q&A DB-MySQL-21-25
  • Q&A DB-MySQL-26-30
  • Q&A DB-MySQL-31-35
  • Q&A DB-MySQL-36-40
  • Q&A DB-MySQL-41-45
  • Q&A DB-MySQL-46-50
  • Q&A Django-1-5
  • Q&A Django-6-10
  • Q&A Django-11-15
  • Q&A Django-16-20
  • Q&A Django-21-25
  • Q&A Django-26-30
  • Q&A Django-31-35
  • Q&A Django-36-40
  • Q&A Django-41-45
  • Q&A Django-46-50
  • Q&A FastAPI-01-05
  • Q&A FastAPI-06-10
  • Q&A FastAPI-11-15
  • Q&A FastAPI-16-20
  • Q&A FastAPI-21-25
  • Q&A FastAPI-26-30
  • Q&A FastAPI-36-40
  • Q&A FastAPI-41-45
  • Q&A FastAPI-31-35
  • Q&A FastAPI-46-50
  • Q&A FastAPI-51-55
  • Q&A FastAPI-56-60
  • Q&A FastAPI-61-65
  • Q&A HTML-01-05
  • Q&A HTML-06-10
  • Q&A HTML-11-15
  • Q&A HTML-16-20
  • Q&A CSS-01-05
  • Q&A CSS-06-10
  • Q&A CSS-11-15
  • Q&A CSS-16-20
  • Q&A JavaScript-1-5
  • Q&A JavaScript-6-10
  • Q&A JavaScript-11-15
  • Q&A JavaScript-16-20
  • Q&A JavaScript-21-25
  • Q&A JavaScript-26-30
  • Q&A JavaScript-31-35
  • Q&A JavaScript-36-40
  • Q&A JavaScript-41-45
  • Q&A JavaScript-46-50
  • Q&A React-1-5
  • Q&A React-6-10
  • Q&A React-11-15
  • Q&A React-16-20
  • Q&A React-21-25
Loading…

Navigate by Range

  • Q&A Python-1-5
  • Q&A Python-6-10
  • Q&A Python-11-15
  • Q&A Python-16-20
  • Q&A Python-21-25
  • Q&A Python-26-30
  • Q&A Python-31-35
  • Q&A Python-36-40
  • Q&A Python-41-45
  • Q&A Python-46-50
  • Q&A Python-51-55
  • Q&A Python-56-60
  • Q&A Python-61-65
  • Q&A Python-66-70
  • Q&A Python-71-75
  • Q&A Python-76-80
  • Q&A Python-81-85
  • Q&A Python-86-90
  • Q&A DB-MySQL-1-5
  • Q&A DB-MySQL-6-10
  • Q&A DB-MySQL-11-15
  • Q&A DB-MySQL-16-20
  • Q&A DB-MySQL-21-25
  • Q&A DB-MySQL-26-30
  • Q&A DB-MySQL-31-35
  • Q&A DB-MySQL-36-40
  • Q&A DB-MySQL-41-45
  • Q&A DB-MySQL-46-50
  • Q&A Django-1-5
  • Q&A Django-6-10
  • Q&A Django-11-15
  • Q&A Django-16-20
  • Q&A Django-21-25
  • Q&A Django-26-30
  • Q&A Django-31-35
  • Q&A Django-36-40
  • Q&A Django-41-45
  • Q&A Django-46-50
  • Q&A FastAPI-01-05
  • Q&A FastAPI-06-10
  • Q&A FastAPI-11-15
  • Q&A FastAPI-16-20
  • Q&A FastAPI-21-25
  • Q&A FastAPI-26-30
  • Q&A FastAPI-36-40
  • Q&A FastAPI-41-45
  • Q&A FastAPI-31-35
  • Q&A FastAPI-46-50
  • Q&A FastAPI-51-55
  • Q&A FastAPI-56-60
  • Q&A FastAPI-61-65
  • Q&A HTML-01-05
  • Q&A HTML-06-10
  • Q&A HTML-11-15
  • Q&A HTML-16-20
  • Q&A CSS-01-05
  • Q&A CSS-06-10
  • Q&A CSS-11-15
  • Q&A CSS-16-20
  • Q&A JavaScript-1-5
  • Q&A JavaScript-6-10
  • Q&A JavaScript-11-15
  • Q&A JavaScript-16-20
  • Q&A JavaScript-21-25
  • Q&A JavaScript-26-30
  • Q&A JavaScript-31-35
  • Q&A JavaScript-36-40
  • Q&A JavaScript-41-45
  • Q&A JavaScript-46-50
  • Q&A React-1-5
  • Q&A React-6-10
  • Q&A React-11-15
  • Q&A React-16-20
  • Q&A React-21-25
StackScholar

StackScholar is your go-to destination for exploring technology from every angle - from bit to supercomputer.

Quick Links

  • Home
  • Search
  • Daily Review
  • Blog
  • About
  • Contact
  • Privacy Policy

DSA Visualizer

  • DSA Visualizer
  • Sorting Algorithms
  • Binary Search Tree
  • Dijkstra's Algorithm
  • A* Pathfinding
  • Dynamic Programming

Rapid Review CS

  • Rapid Review CS
  • Operating Systems
  • DBMS
  • Computer Networks
  • Data Structures & Algorithms
  • Computer Architecture

Interview Preparation

  • System Design Interview
  • System Design Toolkit
  • System Design Patterns
  • Python Full-Stack Interview
  • AI/ML Engineer Interview
  • ML Mock Interview
  • AI/ML Glossary

Get new lessons and visualizers in your inbox

Occasional email when something substantial ships. No spam, unsubscribe anytime.

© 2026 StackScholar. All rights reserved.

Python Full-Stack Interview Questions 81–85 (Classic Algorithms I)

Welcome to this lesson on fundamental Python algorithms. These are some of the most common, classic coding questions you might encounter in an interview. They aren't "trick" questions; they are designed to test your core problem-solving skills, your understanding of data structures, and your ability to write clean, efficient code. We'll cover each one with clear explanations, analogies, and runnable examples. Let's dive in!

81. Write a Python program to find duplicates in a list.

This is a common question with several great answers. The interviewer is looking to see if you can move from a simple solution to a more efficient one.

Analogy: Imagine you are a bouncer at a party. You need to find out who has a "duplicate" name.

  • Method 1 (Using a Set):You get a clipboard (a setcalled `seen` ). When a person (number) arrives, you check your clipboard. If their name is already on it, they are a duplicate! If not, you add their name to the clipboard. This is O(n) time and O(n) space.
  • Method 2 (Using Counter):This is a very "Pythonic" way. You just count everyone, and then report all the names that had a count greater than 1.

Example: Method 1 (Using a Set)

def find_duplicates_set(nums):
    seen = set()
    duplicates = set()
    
    for num in nums:
        if num in seen:
            duplicates.add(num)
        else:
            seen.add(num)
            
    return list(duplicates)

# --- Usage ---
my_list = [1, 2, 3, 4, 2, 5, 6, 1, 8, 3]
print(f"List: {my_list}")
print(f"Duplicates (set): {find_duplicates_set(my_list)}")

Expected Output:

List: [1, 2, 3, 4, 2, 5, 6, 1, 8, 3]
Duplicates (set): [1, 2, 3]

Example: Method 2 (Using `collections.Counter`)

from collections import Counter

def find_duplicates_counter(nums):
    # Counter builds a hash map of {item: count}
    counts = Counter(nums)
    
    # Use a list comprehension to find items with count > 1
    return [item for item, count in counts.items() if count > 1]
    
# --- Usage ---
my_list = [1, 2, 3, 4, 2, 5, 6, 1, 8, 3]
print(f"List: {my_list}")
print(f"Duplicates (Counter): {find_duplicates_counter(my_list)}")

Expected Output:

List: [1, 2, 3, 4, 2, 5, 6, 1, 8, 3]
Duplicates (Counter): [1, 2, 3]

82. Write a Python program to detect a cycle in a linked list.

This is a famous algorithm problem. The standard solution is Floyd's Tortoise and Hare (fast and slow pointer) algorithm.

Analogy: Imagine two runners on a track.

  • `slow` pointer: A runner who moves one step at a time.
  • `fast` pointer: A runner who moves two steps at a time.

If the track is a straight line (no cycle), the fast runner will just reach the end. But if the track is a loop, the fast runner will eventually "lap" the slow runner, and they will land on the same spot. We just have to check if they ever meet.

# First, define the ListNode
class ListNode:
    def __init__(self, val=0, next=None):
        self.val = val
        self.next = next

def has_cycle(head: ListNode | None) -> bool:
    if not head or not head.next:
        return False
        
    slow = head
    fast = head.next
    
    while fast and fast.next:
        if slow == fast:
            return True # Cycle detected!
            
        slow = slow.next
        fast = fast.next.next
        
    return False # Reached the end, no cycle

# --- Usage ---

# 1. Create a list WITH a cycle
node1 = ListNode(1)
node2 = ListNode(2)
node3 = ListNode(3)
node4 = ListNode(4)

node1.next = node2
node2.next = node3
node3.next = node4
node4.next = node2  # <-- This creates the cycle (4 points back to 2)

print(f"List 1 (1->2->3->4->2...): Has cycle? {has_cycle(node1)}")


# 2. Create a list WITHOUT a cycle
node5 = ListNode(5)
node6 = ListNode(6)
node5.next = node6

print(f"List 2 (5->6): Has cycle? {has_cycle(node5)}")

Expected Output:

List 1 (1->2->3->4->2...): Has cycle? True
List 2 (5->6): Has cycle? False

83. Write a Python program to implement binary search.

Binary search is a very efficient algorithm for finding an item in a sorted list . This is a critical pre-condition; it will not work on an unsorted list.

Analogy: You're looking for the word "Python" in a 1,000-page dictionary.

  • You don't start at page 1. You open to the middle (page 500), which has words starting with 'M'.
  • You know 'P' comes after 'M', so you ignore the entire first half (pages 1-500).
  • You take the second half (pages 501-1000) and open to its middle (page 750), which has 'R'.
  • You know 'P' comes before 'R', so you ignore the second half (pages 751-1000).

You repeat this, cutting the problem in half every time, which is extremely fast. This is an O(log n) algorithm.

def binary_search(sorted_list, target):
    """
    Finds the index of a target in a sorted list.
    Returns -1 if the target is not found.
    """
    left = 0
    right = len(sorted_list) - 1
    
    while left <= right:
        # Calculate mid-point, avoiding overflow
        mid = (left + right) // 2 
        
        if sorted_list[mid] == target:
            return mid # Found it!
        elif sorted_list[mid] < target:
            # Target is in the right half
            left = mid + 1
        else:
            # Target is in the left half
            right = mid - 1
            
    return -1 # Target not in the list

# --- Usage ---
my_sorted_list = [2, 5, 7, 13, 19, 25, 30, 42]
target1 = 19
target2 = 100

print(f"List: {my_sorted_list}")
print(f"Find {target1}: Index {binary_search(my_sorted_list, target1)}")
print(f"Find {target2}: Index {binary_search(my_sorted_list, target2)}")

Expected Output:

List: [2, 5, 7, 13, 19, 25, 30, 42]
Find 19: Index 4
Find 100: Index -1

84. Write a Python program to generate Fibonacci numbers.

The Fibonacci sequence is a series where each number is the sum of the two preceding ones, starting from 0 and 1. (0, 1, 1, 2, 3, 5, 8, 13, ...)

While you can solve this with recursion, it's very inefficient (O(2^n)). The iterativesolution is much better (O(n)).

A generator is the most "Pythonic" way to handle this, as it generates the numbers one by one without storing the whole sequence in memory.

def fib_generator(n_terms):
    """
    A generator that yields Fibonacci numbers up to n_terms.
    """
    # Start with the first two numbers
    a, b = 0, 1
    
    count = 0
    while count < n_terms:
        yield a
        
        # This is the magic:
        # The new 'a' becomes 'b'
        # The new 'b' becomes 'a + b'
        a, b = b, a + b
        count += 1

# --- Usage ---
print("First 10 Fibonacci numbers:")
# We can use the generator in a for loop
fib_seq = []
for num in fib_generator(10):
    fib_seq.append(num)

print(fib_seq)

# Or convert it directly to a list
print(f"First 5: {list(fib_generator(5))}")

Expected Output:

First 10 Fibonacci numbers:
[0, 1, 1, 2, 3, 5, 8, 13, 21, 34]
First 5: [0, 1, 1, 2, 3]

85. Write a Python program to check for prime numbers.

A prime number is a number greater than 1 that has no divisors other than 1 and itself.

The key optimization is that you only need to check for divisors up to the square root of the number.

Analogy: If you are looking for factors of 100, once you find 2 (and its pair, 50), you don't need to check 50. If you find 4 (and 25), you don't need to check 25. The "halfway" point for factors is the square root (which is 10). If you haven't found a factor by the time you reach 10, you won't find one after.

import math

def is_prime(n):
    """Checks if a number is prime."""
    
    # 1. Handle edge cases
    if n < 2:
        return False
    if n == 2:
        return True
    
    # 2. Handle even numbers (optimization)
    if n % 2 == 0:
        return False
        
    # 3. Check odd divisors up to the square root
    # We only check odd numbers (3, 5, 7...)
    limit = int(math.sqrt(n)) + 1
    for i in range(3, limit, 2):
        if n % i == 0:
            return False
            
    return True

# --- Usage ---
test_numbers = [1, 2, 3, 4, 17, 25, 97]
print("--- Prime Number Check ---")
for num in test_numbers:
    print(f"Is {num} prime? {is_prime(num)}")

Expected Output:

--- Prime Number Check ---
Is 1 prime? False
Is 2 prime? True
Is 3 prime? True
Is 4 prime? False
Is 17 prime? True
Is 25 prime? False
Is 97 prime? True

Tip: These questions are all about clarity and efficiency. Always state your assumptions (like "this list must be sorted" for binary search) and talk through the time complexity (like O(n) or O(log n)) if you can. Good luck!

Check your understanding

3 questions · no sign-up, nothing stored

0/3 answered
Question 1

1.Why is Floyd's cycle detection preferred over a set of visited nodes?

Question 2

2.Why write mid = lo + (hi - lo) // 2 instead of (lo + hi) // 2?

Question 3

3.Naive recursive fib(n) is O(2ⁿ). What makes memoisation collapse it to O(n)?

0 / 74 ranges

Progress is stored in this browser only - no sign-up, nothing sent anywhere.

Watch these run

Step through the algorithms behind these answers one operation at a time, forwards or backwards, with the code highlighted as it runs.

Floyd's cycle detection

Tortoise and hare, plus the algebra behind why restarting at the head finds the loop entry.

Binary search

Including the overflow bug that sat in the JDK for nine years.

Recursion and the call stack

The Fibonacci question, with the call tree drawn and a memoisation toggle.

Hash table with chaining

The set-based duplicate check, and what it costs when keys collide.

PreviousNext