Data Structures Mastery

Linked Lists, Stacks & Queues

4 min read

These data structures test your ability to work with pointers and understand LIFO/FIFO ordering -- skills that come up in many interview problems.

Linked Lists

A linked list stores elements in nodes connected by pointers. Key differences from arrays:

Feature Array Linked List
Access by index O(1) O(n)
Insert at beginning O(n) O(1)
Insert at end O(1)* O(n) or O(1) with tail
Memory Contiguous Scattered
Cache performance Better Worse

Essential Linked List Patterns:

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

# Pattern 1: Reverse a linked list
def reverse_list(head):
    prev, curr = None, head
    while curr:
        next_node = curr.next
        curr.next = prev
        prev = curr
        curr = next_node
    return prev

# Pattern 2: Fast/Slow pointers (Floyd's cycle detection)
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

# Pattern 3: Find middle of linked list
def find_middle(head):
    slow = fast = head
    while fast and fast.next:
        slow = slow.next
        fast = fast.next.next
    return slow

Interview Tip: The fast/slow pointer technique solves many linked list problems: cycle detection, finding the middle, finding the nth node from the end, and detecting intersection points.

Stacks (LIFO)

Stacks follow Last-In-First-Out ordering. They are essential for:

  • Matching parentheses -- the classic interview question
  • Monotonic stack -- next greater/smaller element
  • Expression evaluation -- postfix, infix conversion
  • DFS traversal -- iterative DFS uses a stack
# Valid parentheses (classic interview question)
def is_valid_parentheses(s):
    stack = []
    mapping = {')': '(', '}': '{', ']': '['}
    for char in s:
        if char in mapping:
            if not stack or stack[-1] != mapping[char]:
                return False
            stack.pop()
        else:
            stack.append(char)
    return len(stack) == 0

# Monotonic stack: next greater element
def next_greater_element(nums):
    result = [-1] * len(nums)
    stack = []  # stores indices
    for i in range(len(nums)):
        while stack and nums[i] > nums[stack[-1]]:
            idx = stack.pop()
            result[idx] = nums[i]
        stack.append(i)
    return result

Queues (FIFO)

Queues follow First-In-First-Out ordering. They are essential for:

  • BFS traversal -- level-order tree traversal, shortest path
  • Sliding window maximum -- using deque (double-ended queue)
  • Task scheduling -- process ordering
from collections import deque

# BFS level-order traversal
def level_order(root):
    if not root:
        return []
    result = []
    queue = deque([root])
    while queue:
        level = []
        for _ in range(len(queue)):
            node = queue.popleft()
            level.append(node.val)
            if node.left:
                queue.append(node.left)
            if node.right:
                queue.append(node.right)
        result.append(level)
    return result

When to Use What

Problem Type Data Structure Example
Matching/nesting Stack Valid parentheses, HTML tags
Next greater/smaller Monotonic Stack Stock prices, temperatures
Level-by-level processing Queue Tree BFS, shortest path
Reverse order Stack Reverse string, undo operations
Cycle detection Linked List + Fast/Slow Linked list cycle, loop detection

Next, we'll explore trees and graphs -- the most complex data structures you'll face in interviews. :::

Quiz

Module 2 Quiz: Data Structures Mastery

Take Quiz