Data Structures & Algorithms (DSA) Interview Questions
Master essential coding interview patterns, algorithm analysis, Big-O complexities, and data structure implementations
Difficulty Filters
Tools & Options
What is Big-O Notation, and how do you calculate Time and Space Complexity?
Big-O notation describes the upper bound (worst-case scenario) of an algorithm's growth rate in terms of time (execution steps) or space (memory usage) relative to the input size N.
Key Complexity Levels:
1. O(1) Constant: Execution time stays constant regardless of N (e.g., array index lookup, hash table search).
2. O(log N) Logarithmic: Input is halved at each step (e.g., Binary Search, BST lookup).
3. O(N) Linear: Time grows proportionally with N (e.g., single loop, linear search).
4. O(N log N) Linearithmic: Efficient sorting algorithms (e.g., Merge Sort, Quick Sort).
5. O(N^2) Quadratic: Nested loops over input N (e.g., Bubble Sort, Matrix multiplication).
6. O(2^N) Exponential: Recursive algorithms solving subproblems independently (e.g., naive Fibonacci).
Space Complexity measures additional memory allocated during execution (excluding input storage). Stack space used by recursive call stacks is counted in auxiliary space.
// O(1) Constant Time
function getFirstElement(arr) {
return arr[0];
}
// O(N) Linear Time
function findMax(arr) {
let max = arr[0];
for (let i = 1; i < arr.length; i++) {
if (arr[i] > max) max = arr[i];
}
return max;
}
// O(log N) Logarithmic Time - Binary Search
function binarySearch(arr, target) {
let low = 0, high = arr.length - 1;
while (low <= high) {
let mid = Math.floor((low + high) / 2);
if (arr[mid] === target) return mid;
else if (arr[mid] < target) low = mid + 1;
else high = mid - 1;
}
return -1;
}How are Arrays stored in memory? What is the difference between Static and Dynamic Arrays?
An Array is a collection of elements stored in contiguous (adjacent) memory locations. Because memory addresses are sequential, any element can be accessed in O(1) constant time using its base address and index formula: address = base_address + index * element_size.
Static Arrays:
- Fixed size allocated at initialization (e.g., in C/C++ or Java standard arrays).
- Memory reallocation is not possible; inserting beyond size causes index out of bounds error.
Dynamic Arrays (e.g., JavaScript Arrays, Python Lists, C++ std::vector):
- Automatically resizes when capacity is exceeded.
- When full, creates a new array with double capacity (usually 2x growth factor) and copies existing elements over.
- Amortized Time Complexity for insertion at end: O(1) average, O(N) worst-case during resize.
// Dynamic Array Resizing Concept
class DynamicArray {
constructor() {
this.capacity = 2;
this.length = 0;
this.data = new Array(this.capacity);
}
push(element) {
if (this.length === this.capacity) {
this._resize(this.capacity * 2); // Double capacity
}
this.data[this.length] = element;
this.length++;
}
_resize(newCapacity) {
const newData = new Array(newCapacity);
for (let i = 0; i < this.length; i++) {
newData[i] = this.data[i];
}
this.data = newData;
this.capacity = newCapacity;
}
}What is a Linked List? Compare Arrays vs Linked Lists and show how to Reverse a Linked List.
A Linked List is a linear data structure where elements (nodes) are stored non-contiguously in memory. Each node contains a data field and a pointer/reference (`next`) to the next node in the list.
Arrays vs Linked Lists Comparison:
- Access Time: Array is O(1) indexed access; Linked List is O(N) sequential traversal.
- Insertion/Deletion at head: Linked List is O(1) pointer updates; Array is O(N) element shifts.
- Insertion at middle/tail: Array is O(N); Linked List is O(1) if node reference is given, otherwise O(N) to traverse.
- Memory Overhead: Linked List uses extra memory for node pointers.
Reversing a Linked List iteratively requires three pointers: `prev`, `curr`, and `next`.
class ListNode {
constructor(val = 0, next = null) {
this.val = val;
this.next = next;
}
}
// Iterative Reversal - O(N) Time, O(1) Space
function reverseLinkedList(head) {
let prev = null;
let curr = head;
while (curr !== null) {
let nextNode = curr.next; // Store next node
curr.next = prev; // Reverse current pointer
prev = curr; // Move prev forward
curr = nextNode; // Move curr forward
}
return prev; // New head of reversed list
}Explain Stacks (LIFO) and Queues (FIFO). How do you solve the Valid Parentheses problem using a Stack?
How does Binary Search work? What are its prerequisites and Time Complexity?
Compare Insertion Sort, Selection Sort, and Bubble Sort. When is Insertion Sort preferred?
Explain the Two Pointers Pattern. How does it optimize Two Sum II (Sorted Array) from O(N^2) to O(N)?
What is the Sliding Window Pattern? Solve 'Maximum Sum Subarray of Size K' and 'Longest Substring Without Repeating Characters'.
Explain Kadane's Algorithm for Maximum Subarray Sum. What is its Time and Space Complexity?
How does Floyd's Cycle Detection Algorithm (Fast & Slow Pointers) detect a loop in a Linked List?
Design a Min Stack that supports push, pop, top, and getMin in O(1) time.
What is a Binary Search Tree (BST)? How do you validate if a Binary Tree is a valid BST?
Compare Tree Traversals: DFS (Preorder, Inorder, Postorder) vs BFS (Level-Order Traversal).
How do you find the Lowest Common Ancestor (LCA) of two nodes in a Binary Tree?
What is a Heap / Priority Queue? Explain Heapify and how to find the Kth Largest Element.
Compare Merge Sort vs Quick Sort in terms of Time, Space, and Stability.
Explain Graph Representations and Graph Traversals: BFS vs DFS.
What is a Trie (Prefix Tree)? Implement Insert, Search, and StartsWith operations.
Explain Bitwise Operations and Bit Tricks: Solve Single Number and Count Set Bits.
Explain Dynamic Programming (DP) Principles: Memoization (Top-Down) vs Tabulation (Bottom-Up).
Solve the 0/1 Knapsack Problem using Dynamic Programming.
Explain the Longest Common Subsequence (LCS) Problem and its DP Solution.
Solve the Coin Change Problem (Minimum Coins required for Amount) using DP.
What is Topological Sort? Implement Kahn's Algorithm (BFS) for Dependency Scheduling.
Explain Dijkstra's Algorithm for Shortest Path in Weighted Graphs.
Explain Disjoint Set Union (DSU / Union-Find) with Path Compression and Union by Rank.
What is a Monotonic Stack? Solve 'Next Greater Element' in O(N) time.
Design an LRU (Least Recently Used) Cache with O(1) Get and Put operations.
How do you find the Median in a Data Stream in O(log N) insert and O(1) findMedian?
Solve the 3Sum Problem in O(N^2) Time using Sorting and Two Pointers.
Solve Top K Frequent Elements using Bucket Sort in O(N) Time.
Technical Interview Mastery Blueprint
Proven methodologies and frameworks to succeed in technical and architecture rounds.
1. The Engineering STAR Technique
When responding to architectural or situational questions, structure your answer using Situation, Technical Constraint, Action, and Measurable Result. Rather than jumping straight to syntax, articulate the business problem, why certain patterns (e.g. caching, queuing, immutability) were selected over alternatives, and what latency or throughput improvements were achieved.
2. Defending Architectural Trade-Offs
Senior interviewers evaluate how you weigh trade-offs. Always explain why you chose an approach: e.g., memory overhead vs CPU cycle speed, consistency vs availability (CAP theorem), or normalized schemas vs denormalized fast reads. Stating the drawbacks of your own proposal demonstrates maturity and production experience.
3. Clean Code & Edge-Case Proactivity
In live-coding rounds, communicate your thinking aloud before typing. State edge cases explicitly: null or undefined inputs, extreme boundary values, concurrency races, and network timeouts. Writing modular, well-named functions with deterministic unit tests separates junior candidates from staff-level engineers.
4. Antipatterns to Avoid
Avoid reciting memorized definitions without practical context. Never dismiss non-functional requirements such as security (CSRF, injection, token rotation), observability (logging, metrics), and accessibility (ARIA, semantic standards). Always ask clarifying scope questions before writing complex implementations.
Explore Related Tools
Hand-picked utilities and calculators related to this tool.
