← Amazon Interview Insights

Amazon·Data Scientist·Technical Phone Screen·Intermediate

Intermediate
May 2026

Summary

Amazon Data Scientist coding screen, one meaty algorithm question with a bunch of follow-ups stacked on top. The core problem felt manageable but the follow-ups kept coming and I wasn't fully prepared for the streaming angle.

Questions Asked (4)

Q1

Write a function that returns the mode(s) of an integer array. If all values are unique, return an empty list. Multiple modes should be returned ordered by first occurrence. The solution should run in O(n) expected time and O(u) space where u is the number of unique values.

Algorithms & Data Structures
Author's notes

I got the core logic pretty fast.

Create a free account to read the full note

AI HintsAI Generated

Suggested Approach

First, clarify the requirements and edge cases, then propose a solution using a hash map to count frequencies and track first occurrence order. After counting, determine the maximum frequency, collect all values with that frequency in order of first occurrence, and return them (or an empty list if all frequencies are 1).

Pro tip: Mention that the solution can be done in a single pass if you maintain the maximum frequency and a list of modes dynamically, but a two-pass approach is simpler and still meets the complexity requirements.

1. Clarify requirements and edge cases

Ask about input constraints (e.g., empty array, negative numbers, large arrays) and confirm that if all values are unique, return an empty list. Also confirm that modes should be ordered by first occurrence.

2. Choose data structures

Use a hash map (dictionary) to count frequencies and a separate list or linked structure to track the order of first occurrence of each unique value.

3. Count frequencies and track order

Iterate through the array once, updating the frequency count for each element. If the element is seen for the first time, add it to the order-tracking list.

4. Find maximum frequency and collect modes

After counting, determine the maximum frequency. Then iterate through the order-tracking list and collect all values whose frequency equals the maximum. If the maximum frequency is 1, return an empty list.

5. Analyze complexity and test

Explain that the time complexity is O(n) expected due to hash map operations, and space is O(u) where u is the number of unique values. Walk through test cases: empty array, all unique, single mode, multiple modes.

Key Points to Mention

  • Use of hash map for O(1) expected frequency counting.
  • Maintaining first occurrence order via a separate list or by leveraging insertion order in Python 3.7+ dictionaries.
  • Handling edge cases: empty array, all unique elements, multiple modes.
  • Time complexity: O(n) expected, space complexity: O(u).
  • Returning modes in order of first occurrence, not sorted order.
  • Potential optimization: single-pass approach to track max frequency and modes dynamically.

AI-generated suggestions, not part of the candidate's original notes. May be inaccurate — verify before relying on them.

Q2

How would you adapt the solution to handle a streaming array of unknown length, emitting current modes over a sliding window of size W, using O(u_window) space?

Algorithms & Data StructuresTechnical Trade-offs
Author's notes

This is where I started flailing.

Create a free account to read the full note

AI HintsAI Generated

Suggested Approach

Start by clarifying the problem: streaming data, unknown length, sliding window of size W, and output current modes with O(u_window) space. Then describe a data structure that maintains frequencies of elements in the window, such as a hash map combined with a bucket structure for frequencies, and explain how to update it as new elements arrive and old elements expire. Finally, discuss how to efficiently retrieve the mode(s) and handle ties, emphasizing the space constraint.

Pro tip: Mention that while O(u_window) space is required, the time complexity per element can be O(1) amortized with careful design, and discuss trade-offs between exact and approximate solutions if the interviewer pushes on scalability.

1. Clarify requirements and constraints

Confirm the definition of 'mode' (most frequent element(s)), whether multiple modes are allowed, and the exact space constraint O(u_window). Also clarify if the window slides by one element at a time and if the stream is infinite.

2. Design the data structure

Propose a hash map to store frequencies of elements in the current window, and a doubly linked list or bucket structure to group elements by frequency. This allows O(1) updates when frequencies change and O(1) access to the current maximum frequency.

3. Handle window updates

When a new element arrives, add it to the window, update its frequency, and adjust the bucket structure. When the window exceeds size W, remove the oldest element, decrement its frequency, and update the structure accordingly. Maintain a pointer to the maximum frequency bucket.

4. Emit current modes

After each update, retrieve all elements in the bucket with the maximum frequency and output them as the current modes. If there are ties, output all. Ensure this operation is efficient, ideally O(number of modes).

5. Analyze complexity and trade-offs

Discuss time complexity per element (O(1) amortized) and space complexity O(u_window). Mention potential optimizations or alternative approaches if exact mode is too costly, such as approximate algorithms (e.g., Misra-Gries, Count-Min Sketch) but note they don't guarantee exact modes.

Key Points to Mention

  • Use a hash map to track frequencies of elements in the window.
  • Maintain a bucket structure (e.g., doubly linked list of frequency buckets) to efficiently find the maximum frequency.
  • Update frequencies in O(1) when adding/removing elements from the sliding window.
  • Handle ties by outputting all elements with the maximum frequency.
  • Space complexity is O(u_window) where u_window is the number of distinct elements in the window.
  • Time complexity per element is O(1) amortized, with mode retrieval O(number of modes).

AI-generated suggestions, not part of the candidate's original notes. May be inaccurate — verify before relying on them.

Q3

How would you handle tie-breaking deterministically when the input is case-insensitive string data, while still preserving stable insertion order?

Algorithms & Data StructuresTechnical Trade-offs
Author's notes

Honestly a bit of a curveball after the integer version.

Create a free account to read the full note

AI HintsAI Generated

Suggested Approach

Start by clarifying the requirements: case-insensitive comparison for tie-breaking, deterministic outcome, and stable insertion order. Then propose a two-level sorting approach: primary sort by the case-insensitive key, and secondary sort by insertion order (e.g., original index) to break ties. Emphasize that this ensures determinism and stability, and discuss trade-offs like memory overhead for storing indices.

Pro tip: Mention that Python's sort is stable, so if you sort by the case-insensitive key only, ties will naturally preserve insertion order—this is a clean, efficient solution. However, if you need to sort by multiple keys, use a tuple with the original index as the last element.

1. Clarify requirements and constraints

Confirm that 'case-insensitive' means comparing strings after lowercasing (or casefolding), and that 'stable insertion order' means preserving the original order of equal elements. Ask about data size, memory limits, and whether the input can be modified.

2. Choose a primary key and tie-breaker

Use the case-insensitive string as the primary sort key. For tie-breaking, use the original insertion index (or a monotonically increasing counter) as the secondary key to guarantee determinism.

3. Leverage stable sorting algorithms

If the language's sort is stable (e.g., Python's Timsort), simply sorting by the case-insensitive key will preserve insertion order for ties. Otherwise, explicitly include the index in the sort key.

4. Implement and test edge cases

Write code that handles empty strings, non-ASCII characters, and duplicate keys. Test with inputs where case variations cause ties to ensure stability and determinism.

5. Discuss trade-offs and alternatives

Compare approaches: stable sort with primary key only vs. explicit index tie-breaker. Consider time/space complexity, and mention that using a custom comparator with index is O(n log n) but may be less efficient than stable sort.

Key Points to Mention

  • Definition of case-insensitive comparison: lowercasing or casefolding, and potential Unicode complexities.
  • Stable sorting: preserving relative order of equal elements, and which algorithms/languages guarantee it.
  • Tie-breaking with original index: ensures determinism even if the sort is not stable.
  • Time and space complexity: O(n log n) time, O(n) space for storing indices or keys.
  • Amazon leadership principles: customer obsession (clarifying requirements), dive deep (edge cases), and insist on highest standards (determinism).
  • Real-world example: sorting a list of user names case-insensitively while keeping the order of duplicates as they were entered.

AI-generated suggestions, not part of the candidate's original notes. May be inaccurate — verify before relying on them.

Q4

What is the worst-case time and space complexity of your solution?

Algorithms & Data Structures
Author's notes

Went fine.

Create a free account to read the full note

AI HintsAI Generated

Suggested Approach

Start by clearly stating the worst-case time and space complexity of your solution using Big-O notation, then briefly explain the reasoning behind each. If possible, compare with average-case or best-case to show depth, and mention any trade-offs you made.

Pro tip: Always relate the complexity back to the problem constraints and business impact—e.g., how it scales with data size—to demonstrate that you think beyond just theoretical bounds.

1. State the complexities

Clearly state the worst-case time and space complexity using Big-O notation, e.g., O(n log n) time and O(n) space.

2. Explain the reasoning

Briefly explain why the complexity is what it is, referencing key operations (e.g., sorting, nested loops, recursion depth) that dominate the runtime or memory usage.

3. Compare with other cases

If relevant, mention average-case or best-case complexity to provide a complete picture and show you understand the algorithm's behavior under different inputs.

4. Discuss trade-offs

Highlight any trade-offs between time and space, or between worst-case and average-case performance, and justify your design choices.

5. Relate to scalability

Connect the complexity to practical implications, such as how the solution scales with increasing data size or how it meets the problem's constraints.

Key Points to Mention

  • Big-O notation for time and space
  • Dominant operations (e.g., loops, recursion, sorting)
  • Worst-case vs. average-case analysis
  • Trade-offs between time and space
  • Scalability and practical implications
  • Justification of design choices based on complexity

AI-generated suggestions, not part of the candidate's original notes. May be inaccurate — verify before relying on them.