Interview Prep — DSA Track
DSA Interview Questions
47 curated DSA questions covering arrays, linked lists, trees, graphs, sorting, and dynamic programming — tagged for FAANG and startups. Check off as you go.
Arrays
Linked Lists
Strings
Trees
Graphs
DP
47Total Qs
8Arrays
6Linked Lists
6Strings
8Trees
7Graphs
6DP
21
What are the essential DSA problem-solving patterns?
DSA
▾
Key Patterns Checklist:
- Two Pointers: Sorted arrays, pair finding, palindrome checking
- Sliding Window: Subarray/substring problems, consecutive elements
- Fast & Slow Pointers: Cycle detection, middle of linked list
- Merge Intervals: Overlapping intervals, scheduling problems
- Cyclic Sort: Arrays with numbers in given range, find duplicates
- In-place Reversal: Linked list reversal, rotate operations
- BFS: Level-order traversal, shortest path (unweighted graphs)
- DFS: Path finding, connected components, backtracking
- Topological Sort: Dependency resolution, task scheduling
- Backtracking: Combinations, permutations, subsets, N-Queens
- Dynamic Programming: Optimization problems, counting problems
- Divide & Conquer: Merge sort, quick sort, binary search variations
- Bit Manipulation: XOR tricks, set operations, power of 2 checks
- Monotonic Stack: Next greater element, largest rectangle in histogram
- Heap/Priority Queue: Top-K elements, median finding, scheduling
Tip: Recognizing the pattern is 80% of solving the problem. Practice identifying which pattern fits which problem type.
22
Explain Recursion with examples. What are base case and recursive case?
DSA
▾
Recursion is when a function calls itself to solve a smaller version of the same problem.
Two Essential Components:
How it works (call stack):
Two Essential Components:
- Base Case: The stopping condition — prevents infinite recursion
- Recursive Case: The function calls itself with a smaller input
python — Factorial Example
# Factorial: n! = n × (n-1) × ... × 1 def factorial(n): # Base case if n == 0 or n == 1: return 1 # Recursive case return n * factorial(n - 1) factorial(5) # 5 × 4 × 3 × 2 × 1 = 120
factorial(5)
→ 5 × factorial(4)
→ 4 × factorial(3)
→ 3 × factorial(2)
→ 2 × factorial(1)
→ 1 (base case!)
→ 2 × 1 = 2
→ 3 × 2 = 6
→ 4 × 6 = 24
→ 5 × 24 = 120
Stack Overflow: Without a base case, recursion continues infinitely until the call stack overflows.
23
What is Memoization? How does it optimize recursion?
DSA
▾
Memoization is caching results of expensive function calls to avoid recomputation.
Example: Fibonacci without vs with memoization
Why it matters:
Example: Fibonacci without vs with memoization
python — Naive vs Memoized
# Naive: O(2^n) - recalculates same values def fib(n): if n <= 1: return n return fib(n-1) + fib(n-2) # Memoized: O(n) - caches results def fib_memo(n, memo={}): if n in memo: return memo[n] if n <= 1: return n memo[n] = fib_memo(n-1, memo) + fib_memo(n-2, memo) return memo[n]
- Without memo: fib(40) takes ~1 second (1+ billion calls)
- With memo: fib(40) takes ~0.0001 seconds (40 calls)
Python's @lru_cache: Use
@functools.lru_cache(maxsize=None) for automatic memoization.
24
What is Tail Recursion? Is it optimized in Python?
DSA
▾
Tail Recursion occurs when the recursive call is the last operation in the function — no computation happens after it returns.
Compiler Optimization: Some languages (Scheme, Scala) optimize tail recursion by reusing the same stack frame — preventing stack overflow.
python — Tail Recursive Factorial
# Tail recursive version def factorial_tail(n, acc=1): if n == 0: return acc return factorial_tail(n - 1, acc * n) # ↑ Nothing happens after this call
Python does NOT optimize tail recursion. Guido van Rossum intentionally left it out. Use iteration instead for deep recursions in Python.
25
Common Recursion Interview Problems
DSA
▾
Classic Problems:
- Fibonacci Number — Base case + two recursive calls
- Climbing Stairs — How many ways to reach step n? (1 or 2 steps at a time)
- Reverse a String — Recursively reverse substring
- Power Function — Calculate x^n recursively (optimize with x^(n/2))
- Merge Sort — Divide array, sort halves, merge
- Quick Sort — Partition around pivot, sort partitions
- Binary Tree Traversals — In-order, pre-order, post-order
- Lowest Common Ancestor — Find LCA in BST
- Permutations/Subsets — Backtracking with recursion
- Combination Sum — Find all combinations that sum to target
python — Climbing Stairs
# You can climb 1 or 2 steps at a time def climbStairs(n): if n <= 2: return n return climbStairs(n-1) + climbStairs(n-2) # With memoization def climbStairs_memo(n, memo={}): if n in memo: return memo[n] if n <= 2: return n memo[n] = climbStairs_memo(n-1) + climbStairs_memo(n-2) return memo[n]
26
What are common misconceptions about programming?
General
▾
7 Common Misconceptions:
- "You need to be good at math" — Logic matters more than calculus. Most programming uses basic arithmetic.
- "Memorizing syntax is key" — Understanding concepts > memorization. Docs exist for a reason.
- "More code = better" — Concise, readable code is superior. Brevity with clarity wins.
- "You need the 'perfect' IDE/language" — Tools don't make the programmer. Fundamentals transfer across languages.
- "Debugging is failure" — Debugging IS programming. Even seniors debug for hours.
- "You must code 8 hours/day" — Quality > quantity. Burnout kills progress. Consistent small efforts compound.
- "AI will replace programmers" — AI augments, not replaces. Understanding fundamentals lets you verify AI output.
Truth: Programming is problem-solving with code. Syntax is just the vocabulary; logic is the language.
01
What is the difference between Array and Linked List?
DSA
▾
Arrays
store elements in contiguous memory, giving
O(1)
random access by index but
O(n)
insert/delete (due to shifting).
Linked Lists
use nodes with pointers, giving
O(1)
insert/delete at head but
O(n)
access.
- Memory: Array = fixed contiguous block; LL = scattered nodes with pointer overhead
- Access: Array O(1) vs LL O(n)
- Insert/Delete at head: Array O(n) vs LL O(1)
- Cache friendliness: Arrays are cache-friendly; LLs cause cache misses
When to use LL:
Frequent insertions/deletions in the middle, or when size is unknown in advance.
02
Explain Big-O notation and give examples of O(1), O(n), O(n²), O(log n).
DSA
▾
Big-O describes the
worst-case growth rate
of an algorithm as input size
n
grows, ignoring constants.
- O(1) — Constant: array index access, hash table lookup
- O(log n) — Logarithmic: binary search, BST operations
- O(n) — Linear: linear search, single loop
- O(n log n) — Merge sort, heap sort, Tim sort
- O(n²) — Quadratic: bubble/selection/insertion sort (worst case), nested loops
- O(2ⁿ) — Exponential: recursive Fibonacci, subset generation
Tip:
Drop constants and lower-order terms — O(2n + 5) simplifies to O(n).
03
What is a Stack and a Queue? Give real-world examples.
DSA
▾
Stack
— LIFO (Last In First Out). Operations: push, pop, peek — all O(1).
Real world: Browser back button, undo/redo, function call stack, balanced parentheses checker.
Queue — FIFO (First In First Out). Operations: enqueue, dequeue — all O(1).
Real world: Print spooler, CPU scheduling, BFS traversal, customer service queues.
Real world: Browser back button, undo/redo, function call stack, balanced parentheses checker.
Queue — FIFO (First In First Out). Operations: enqueue, dequeue — all O(1).
Real world: Print spooler, CPU scheduling, BFS traversal, customer service queues.
Deque
(double-ended queue) supports insert/delete at both ends — used for sliding window maximum problems.
04
Explain Binary Search Tree (BST) and its time complexities.
DSA
▾
A BST is a binary tree where for every node:
left subtree < node < right subtree
.
- Search: O(log n) average, O(n) worst (skewed tree)
- Insert: O(log n) average, O(n) worst
- Delete: O(log n) average
- In-order traversal: produces sorted output
Worst case O(n)
happens when elements are inserted in sorted order (creates a chain). AVL and Red-Black trees fix this with self-balancing.
05
What is Dynamic Programming? How is it different from recursion?
DSA
▾
Dynamic Programming (DP)
solves problems by breaking them into overlapping subproblems and
storing results to avoid recomputation
(memoization or tabulation).
- Recursion: recomputes subproblems — exponential time in many cases
- DP (top-down memoization): recursion + caching = O(n) for Fibonacci
- DP (bottom-up tabulation): iterative, fills a table from base cases up
Examples:
0/1 Knapsack, LCS, LIS, Coin Change, Edit Distance, Matrix Chain Multiplication.
06
Explain BFS vs DFS. When would you use each?
DSA
▾
BFS (Breadth-First Search):
Uses a queue. Explores level by level.
Use when: Shortest path in unweighted graph, level-order traversal, nearest neighbour problems.
DFS (Depth-First Search): Uses a stack (or recursion). Explores as deep as possible first.
Use when: Cycle detection, topological sort, connected components, maze solving, tree traversals.
Use when: Shortest path in unweighted graph, level-order traversal, nearest neighbour problems.
DFS (Depth-First Search): Uses a stack (or recursion). Explores as deep as possible first.
Use when: Cycle detection, topological sort, connected components, maze solving, tree traversals.
- Both: O(V + E) time, O(V) space
- BFS guarantees shortest path (unweighted); DFS does not
07
What is a Hash Table and how does it handle collisions?
DSA
▾
A
Hash Table
stores key-value pairs using a hash function to map keys to array indices. Average
O(1)
for insert, delete, lookup.
Collision handling techniques:
Collision handling techniques:
- Chaining: each bucket holds a linked list of entries
- Open Addressing: probe for next empty slot (linear probing, quadratic probing, double hashing)
Load factor
= n/k (items/buckets). When it exceeds ~0.7, the table is resized (rehashing). Python's
dict
uses open addressing.
08
Compare Merge Sort and Quick Sort.
DSA
▾
- Merge Sort: O(n log n) always, stable, O(n) extra space (not in-place). Good for linked lists and external sorting.
- Quick Sort: O(n log n) average, O(n²) worst, O(log n) space (in-place). Faster in practice due to cache efficiency.
Python uses Timsort
(hybrid merge + insertion sort) — O(n log n) worst case, stable, adaptive.
09
What is a Heap and where is it used?
DSA
▾
A
Heap
is a complete binary tree satisfying the heap property:
Max-heap: parent ≥ children. Min-heap: parent ≤ children.
Operations: Insert O(log n), Extract-min/max O(log n), Peek O(1).
Uses: Priority queues, Dijkstra's algorithm, Heap Sort, Top-K problems, scheduling.
Max-heap: parent ≥ children. Min-heap: parent ≤ children.
Operations: Insert O(log n), Extract-min/max O(log n), Peek O(1).
Uses: Priority queues, Dijkstra's algorithm, Heap Sort, Top-K problems, scheduling.
Python's
heapq
module implements a min-heap. For max-heap, negate values.
10
What is the Two Pointer technique? Give an example.
DSA
▾
The
Two Pointer
technique uses two indices moving through an array to solve problems in O(n) instead of O(n²).
Other uses:
Remove duplicates, 3Sum, container with most water, palindrome check.
python
# Two Sum in sorted array def two_sum(arr, target): left, right = 0, len(arr) - 1 while left < right: s = arr[left] + arr[right] if s == target: return [left, right] elif s < target: left += 1 else: right -= 1
11
What is the Sliding Window technique? When is it used?
DSA
▾
The
Sliding Window
technique converts nested loops into a single pass by maintaining a "window" over the array.
Fixed-size window: Max sum of k consecutive elements.
Variable-size window: Smallest subarray with sum ≥ target.
Fixed-size window: Max sum of k consecutive elements.
Variable-size window: Smallest subarray with sum ≥ target.
Pattern:
Expand window (right++), shrink when condition met (left++), track answer.
12
How do you detect a cycle in a Linked List?
DSA
▾
Use
Floyd's Cycle Detection
(Tortoise and Hare algorithm):
- Slow pointer moves 1 step, fast pointer moves 2 steps
- If there's a cycle, they will meet
- Time: O(n), Space: O(1)
python
def has_cycle(head): slow = fast = head while fast and fast.next: slow = slow.next fast = fast.next.next if slow == fast: return True return False
13
Reverse a Linked List (iterative and recursive).
DSA
▾
Iterative:
Recursive:
python
def reverse_list(head): prev, curr = None, head while curr: next_temp = curr.next curr.next = prev prev = curr curr = next_temp return prev
python
def reverse_list(head): if not head or not head.next: return head new_head = reverse_list(head.next) head.next.next = head head.next = None return new_head
14
How do you check if a string is a palindrome?
DSA
▾
Two pointer approach:
Python one-liner:
python
def is_palindrome(s): left, right = 0, len(s)-1 while left < right: if s[left] != s[right]: return False left += 1; right -= 1 return True
return s == s[::-1]
15
Find the first non-repeating character in a string.
DSA
▾
Use a hash map to count frequencies, then iterate to find first with count = 1.
Time: O(n), Space: O(1) (max 26 lowercase letters)
python
from collections import Counter def first_unique(s): counts = Counter(s) for i, ch in enumerate(s): if counts[ch] == 1: return i return -1
16
What are the different tree traversals? Explain each.
DSA
▾
- In-order (Left, Root, Right): BST gives sorted output
- Pre-order (Root, Left, Right): Used for tree copying, serialization
- Post-order (Left, Right, Root): Used for tree deletion, expression trees
- Level-order (BFS): Level by level using a queue
python
# In-order traversal def inorder(root): if root: inorder(root.left) print(root.val) inorder(root.right)
17
Find the height/depth of a Binary Tree.
DSA
▾
Height = number of edges on longest path from root to leaf.
Time: O(n), Space: O(h) for recursion stack
python
def max_depth(root): if not root: return 0 return 1 + max(max_depth(root.left), max_depth(root.right))
18
Explain Dijkstra's shortest path algorithm.
DSA
▾
Dijkstra finds the shortest path from a source to all other nodes in a weighted graph (non-negative edges).
- Use a min-heap (priority queue)
- Always process the node with smallest tentative distance
- Relax edges: if dist[u] + weight < dist[v], update dist[v]
19
What is Topological Sort? When is it used?
DSA
▾
Topological sort orders vertices in a DAG such that for every edge (u→v), u comes before v.
Uses: Task scheduling, dependency resolution, build systems.
Kahn's algorithm: Use in-degree counting + queue.
DFS approach: Post-order traversal + reverse.
Uses: Task scheduling, dependency resolution, build systems.
Kahn's algorithm: Use in-degree counting + queue.
DFS approach: Post-order traversal + reverse.
20
Explain the Coin Change problem and its DP solution.
DSA
▾
Given coins of different denominations and a total amount, find the minimum number of coins needed.
Time: O(amount × coins), Space: O(amount)
python
def coin_change(coins, amount): dp = [float('inf')] * (amount + 1) dp[0] = 0 for coin in coins: for x in range(coin, amount + 1): dp[x] = min(dp[x], dp[x - coin] + 1) return dp[amount] if dp[amount] != float('inf') else -1
DSA Master Roadmap
Complete Learning Path: Follow this structured roadmap to master DSA systematically.
DSA MASTER TREE
│
├── 1. Foundations
│ ├── What is Data Structure
│ ├── What is Algorithm
│ ├── Time Complexity
│ │ ├── Big-O
│ │ ├── Big-Ω
│ │ └── Big-Θ
│ ├── Space Complexity
│ └── Recurrence Relations
│
├── 2. Mathematical Basics
│ ├── Logarithms
│ ├── Modular Arithmetic
│ ├── Prime Numbers
│ ├── GCD / LCM
│ └── Sieve of Eratosthenes
│
├── 3. Arrays
│ ├── Traversal
│ ├── Searching
│ │ ├── Linear Search
│ │ └── Binary Search
│ ├── Prefix Sum
│ ├── Sliding Window
│ ├── Two Pointers
│ ├── Kadane's Algorithm
│ └── Matrix / 2D Arrays
│
├── 4. Strings
│ ├── String Manipulation
│ ├── Pattern Matching
│ │ ├── Naive
│ │ ├── KMP
│ │ ├── Rabin-Karp
│ │ └── Z Algorithm
│ ├── Palindrome Problems
│ ├── String Hashing
│ └── Trie
│
├── 5. Linked Lists
│ ├── Singly Linked List
│ ├── Doubly Linked List
│ ├── Circular Linked List
│ ├── Reverse Linked List
│ ├── Cycle Detection (Floyd)
│ └── Merge Lists
│
├── 6. Stack
│ ├── Stack Implementation
│ ├── Balanced Parentheses
│ ├── Next Greater Element
│ ├── Monotonic Stack
│ └── Min Stack
│
├── 7. Queue
│ ├── Queue Implementation
│ ├── Circular Queue
│ ├── Deque
│ ├── Priority Queue
│ └── Monotonic Queue
│
├── 8. Hashing
│ ├── Hash Tables
│ ├── Collision Handling
│ │ ├── Chaining
│ │ └── Open Addressing
│ ├── Load Factor
│ └── Rehashing
│
├── 9. Trees
│ ├── Binary Tree
│ │ ├── Traversals
│ │ │ ├── Inorder
│ │ │ ├── Preorder
│ │ │ └── Postorder
│ │ ├── Height / Depth
│ │ └── Diameter
│ ├── Binary Search Tree
│ ├── AVL Tree
│ ├── Red-Black Tree
│ ├── Segment Tree
│ ├── Fenwick Tree
│ └── Heap
│ ├── Min Heap
│ └── Max Heap
│
├── 10. Graphs
│ ├── Graph Representation
│ │ ├── Adjacency Matrix
│ │ └── Adjacency List
│ ├── BFS
│ ├── DFS
│ ├── Topological Sort
│ ├── Cycle Detection
│ ├── Shortest Path
│ │ ├── Dijkstra
│ │ ├── Bellman-Ford
│ │ └── Floyd-Warshall
│ ├── Minimum Spanning Tree
│ │ ├── Kruskal
│ │ └── Prim
│ └── Disjoint Set (Union-Find)
│
├── 11. Recursion & Backtracking
│ ├── Recursion Basics
│ ├── Subsets
│ ├── Permutations
│ ├── N-Queens
│ └── Sudoku Solver
│
├── 12. Greedy Algorithms
│ ├── Activity Selection
│ ├── Huffman Coding
│ ├── Fractional Knapsack
│ └── Job Scheduling
│
├── 13. Dynamic Programming
│ ├── Memoization
│ ├── Tabulation
│ ├── 1D DP
│ ├── 2D DP
│ ├── Knapsack Variants
│ ├── Longest Common Subsequence
│ ├── Longest Increasing Subsequence
│ └── Matrix Chain Multiplication
│
├── 14. Bit Manipulation
│ ├── Bitwise Operators
│ ├── Set / Clear Bits
│ ├── Count Set Bits
│ └── XOR Tricks
│
├── 15. Advanced DSA
│ ├── Sparse Table
│ ├── Heavy-Light Decomposition
│ ├── Treap
│ ├── Splay Tree
│ └── Skip List
│
└── 16. Interview Patterns
├── Two Pointer Pattern
├── Sliding Window Pattern
├── Binary Search Pattern
├── BFS / DFS Pattern
├── Greedy Choice Pattern
└── DP Pattern Recognition
No questions match your filter.