Design a Max Heap

Data Structures
Medium
Google
144.1K views

Implement the core operations of a Max Heap (`insert`, `getMax`, `extractMax`) using an array. Ensure the heap property is maintained through `swim` and `sink` operations.

Why Interviewers Ask This

Google interviewers ask this to evaluate your ability to translate abstract data structure theory into efficient, bug-free code under pressure. They specifically test your understanding of the heap property, array indexing math (parent/child relationships), and your capacity to implement O(log n) operations like swim and sink without relying on built-in libraries.

How to Answer This Question

1. Clarify requirements: Confirm if you need a generic max-heap or one handling duplicates, and agree on using an array for storage. 2. Define the contract: Explicitly state the parent-child index formulas (i.e., left child is 2*i + 1, parent is floor((i-1)/2)). 3. Implement helper methods first: Draft 'swim' for insertion and 'sink' for removal before writing the main logic to ensure correctness. 4. Code insert: Add element at end, then call swim to bubble it up while maintaining the max-heap invariant. 5. Code extractMax: Swap root with last element, remove root, then sink the new root down to restore order. 6. Verify edge cases: Test empty heap scenarios and single-element arrays to demonstrate robustness.

Key Points to Cover

  • Explicitly stating the mathematical formulas for parent and child indices upfront
  • Separating helper logic (swim/sink) from main operations for cleaner code
  • Demonstrating awareness of time complexity for each operation (O(log n) vs O(1))
  • Handling edge cases like empty heaps or single-element arrays gracefully
  • Avoiding standard library imports to show deep algorithmic understanding

Sample Answer

To design a Max Heap efficiently, I will use an array to store elements, leveraging the mathematical properties of binary trees. First, I define the core invariants: for any node at index i, its children are at 2i+1 and 2i+2, and its parent is at floor((i-1)/2). This allows O(1) access without pointers. For insertion, I place the new element at the end of the array and invoke the 'swim' operation. In swim, I compare the element with its parent; if it is larger, I swap them and repeat until the heap property is restored. This ensures O(log n) complexity. For extraction, I save the root value, swap it with the last element, and decrement the size. Then, I trigger 'sink' on the new root. Sink compares the node with its children, swapping with the larger child if necessary, and repeats downward. Finally, getMax simply returns the root element in O(1) time. I will handle boundary checks immediately to prevent index out-of-bounds errors, ensuring the solution is production-ready.

Common Mistakes to Avoid

  • Using 1-based indexing instead of 0-based indexing which breaks the parent/child math
  • Forgetting to swap the last element with the root before sinking during extraction
  • Implementing swim or sink recursively without considering stack overflow risks
  • Neglecting to check if the heap is empty before attempting to get or extract the maximum

Practice This Question with AI

Answer this question orally or via text and get instant AI-powered feedback on your response quality, structure, and delivery.

Start Practicing

Related Interview Questions

Browse all 154 Data Structures questionsBrowse all 87 Google questions