← Meta Interview Insights

Meta·Software Engineer·Onsite - Coding / Algorithms·Senior

Senior
Jun 2026

Summary

Went through what felt like a gauntlet of algorithm and design questions for a software engineering role at Meta. Four pretty dense problems back to back, covering everything from string parsing to stock trading variants. Not a casual screen.

Questions Asked (4)

Q1

Given a text document, implement a word counter that handles edge cases like contractions, hyphenated compounds, numerals, Unicode, and emojis. Define your tokenization policy explicitly, then build a streaming solution for very large files. Discuss time and space complexity and provide test cases.

Algorithms & Data StructuresTechnical Trade-offs
Author's notes

I spent probably too long defining what a 'word' even is before writing a single line of code.

Create a free account to read the full note

AI HintsAI Generated

Suggested Approach

Start by explicitly defining a tokenization policy that specifies how to handle contractions, hyphenated compounds, numerals, Unicode, and emojis, then implement a streaming word counter using a state machine or regex-based tokenizer that processes input in chunks. Discuss time and space complexity, and provide test cases covering edge cases and large files.

Pro tip: Emphasize that the tokenization policy is a product decision—clarify requirements with the interviewer before coding, and mention that streaming avoids loading the entire file into memory, which is crucial for scalability.

1. Clarify requirements and define tokenization policy

Ask clarifying questions about what constitutes a 'word' (e.g., are contractions one word or two? Should emojis count as words?). Explicitly state your policy for each edge case: contractions (e.g., 'don't' as one token), hyphenated compounds (e.g., 'well-known' as one token), numerals (e.g., '123' as a word), Unicode (e.g., accented characters as part of words), and emojis (e.g., each emoji as a separate token).

2. Design a streaming tokenizer

Outline a streaming approach that reads the file in chunks (e.g., 4KB blocks) and uses a finite state machine or regex to identify word boundaries. Handle partial tokens at chunk boundaries by carrying over state. For Unicode and emojis, consider using a library or code point iteration to correctly identify characters.

3. Implement the word counter

Write pseudocode or actual code for the streaming counter. Use a hash map to count word frequencies if needed, or just a counter for total words. Ensure the tokenizer correctly applies the policy from step 1. Discuss how to handle very large files without loading them entirely into memory.

4. Analyze time and space complexity

State that time complexity is O(n) where n is the number of characters, as each character is processed once. Space complexity is O(1) for total word count (or O(k) for word frequency map where k is unique words), plus O(chunk size) for buffering. Emphasize that streaming keeps memory usage constant regardless of file size.

5. Provide test cases and discuss trade-offs

List test cases: empty file, file with only punctuation, contractions, hyphenated words, numerals, Unicode text, emojis, mixed content, and a large file to test streaming. Discuss trade-offs between different tokenization policies (e.g., simplicity vs. correctness) and potential performance implications of regex vs. manual state machine.

Key Points to Mention

  • Explicit tokenization policy for contractions, hyphenated compounds, numerals, Unicode, and emojis
  • Streaming architecture using chunked reading and state machine to handle large files
  • Time complexity O(n) and space complexity O(1) for total count (or O(k) for frequency map)
  • Handling of Unicode and emojis via code point iteration or libraries
  • Test cases covering edge cases and large files
  • Trade-offs between different tokenization approaches and their impact on performance and correctness

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

Q2

Design and implement a generic Node class for a rooted tree where each node can have any number of children. Include addChild, removeChild, moveSubtree, preorder and breadth-first traversal, and a find method that returns the path from root. Enforce that cycles are impossible and discuss complexity for each operation.

Algorithms & Data StructuresTechnical Trade-offs
Author's notes

The cycle prevention piece is what made this interesting.

Create a free account to read the full note

AI HintsAI Generated

Suggested Approach

Start by clarifying the requirements and defining the Node class with parent and children references to enforce tree invariants. Implement each operation with careful pointer updates, ensuring cycle prevention by checking ancestry before moves. Analyze time and space complexity for each operation, highlighting trade-offs between simplicity and efficiency.

Pro tip: Mention that storing a parent pointer enables O(1) cycle detection during moveSubtree, but requires careful updates to maintain consistency. Also, discuss how the choice of data structure for children (e.g., list vs. set) affects removeChild complexity.

1. Clarify requirements and design

Confirm that the tree is rooted, nodes can have any number of children, and operations must maintain acyclic structure. Decide on storing parent and children references.

2. Implement core operations

Write addChild, removeChild, and moveSubtree with proper pointer updates. For moveSubtree, check that the new parent is not a descendant of the moved node to prevent cycles.

3. Implement traversals and find

Implement preorder (DFS) and breadth-first (BFS) traversals using recursion/stack and queue respectively. For find, traverse from root or use parent pointers to build path.

4. Analyze complexity and discuss trade-offs

For each operation, state time and space complexity. Discuss how using parent pointers affects moveSubtree and find, and trade-offs between different child data structures.

Key Points to Mention

  • Cycle prevention: check if target parent is in the subtree of the node being moved (using parent pointers or traversal).
  • Time complexity: addChild O(1), removeChild O(k) where k is number of children (or O(1) with doubly-linked list), moveSubtree O(n) for cycle check, traversals O(n), find O(n) or O(depth) with parent pointers.
  • Space complexity: O(n) for tree storage, O(h) for recursion stack in preorder, O(w) for BFS queue where w is max width.
  • Trade-offs: parent pointers simplify moveSubtree and find but increase memory and require updates; using a set for children makes removeChild O(1) but may increase constant factors.
  • Edge cases: moving root, moving to same parent, removing non-existent child, finding non-existent value.
  • Invariant maintenance: ensure parent-child consistency after each operation, especially during moveSubtree.

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

Q3

Given a string and a dictionary of valid words, determine if the string can be segmented into a sequence of dictionary words. Return a valid segmentation if one exists, or an empty result if not. Optimize for repeated queries against the same fixed dictionary and very long input strings.

Algorithms & Data Structures
Author's notes

Classic word break problem but the 'optimize for many queries on a fixed dictionary' angle changed things.

Create a free account to read the full note

AI HintsAI Generated

Suggested Approach

Start by clarifying the problem constraints and then propose a solution that preprocesses the dictionary into a trie for efficient word lookups. Use dynamic programming with memoization to determine if the string can be segmented, and backtrack to reconstruct a valid segmentation. Optimize for repeated queries by caching results and using the trie to quickly prune invalid paths.

Pro tip: Emphasize the trade-offs between preprocessing time and query time, and mention that for very long strings, an iterative DP with a trie avoids recursion depth issues and is more cache-friendly.

1. Clarify requirements and constraints

Ask about the expected length of strings, number of queries, dictionary size, and whether the dictionary is fixed. Confirm if any segmentation is acceptable or if there are preferences (e.g., longest words first).

2. Choose data structures

Propose building a trie from the dictionary for O(L) word lookups, where L is the max word length. Consider using a set for O(1) lookups if the dictionary is small, but highlight trie's advantage for prefix pruning.

3. Design DP algorithm

Define dp[i] as whether the substring from i to end can be segmented. Iterate from the end, and for each i, check all possible words starting at i using the trie. Store the next index for reconstruction.

4. Optimize for repeated queries

Cache results for previously seen suffixes or entire strings. If the dictionary is fixed, precompute the trie once. Use memoization to avoid recomputing overlapping subproblems across queries.

5. Reconstruct and return segmentation

After DP, if segmentation is possible, backtrack using the stored next indices to build the list of words. If not, return an empty result.

Key Points to Mention

  • Trie data structure for efficient prefix matching and word lookup
  • Dynamic programming with memoization to avoid redundant computations
  • Time complexity: O(N * L) per query with trie, where N is string length and L is max word length
  • Space complexity: O(N) for DP array and O(total characters) for trie
  • Handling very long strings: iterative DP to avoid stack overflow, and possible use of bitsets for optimization
  • Caching strategies for repeated queries: memoizing results for suffixes or entire strings

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

Q4

Given stock prices by day, find the buy and sell days that maximize profit with exactly one transaction and return the day indices. Then extend to at most two transactions with a mandatory one-day cooldown after each sell, plus an optional fixed fee per sell. Provide the algorithm, correctness reasoning, and complexity.

Algorithms & Data StructuresTechnical Trade-offs
Author's notes

The single transaction part took about two minutes.

Create a free account to read the full note

AI HintsAI Generated

Suggested Approach

Start by solving the single-transaction case with a linear scan tracking minimum price and max profit, then generalize to two transactions with cooldown and fee using dynamic programming with states (holding, sold, cooldown). Clearly define state transitions and validate with edge cases like decreasing prices or fees exceeding profits.

Pro tip: Emphasize the state machine formulation for the extended problem—it shows you can model complex constraints cleanly and reason about correctness, which Meta values for production code. Also, mention that the fee can be incorporated by subtracting it at the sell transition.

1. Clarify problem constraints and edge cases

Confirm input format (array of prices), output (indices for single transaction, max profit for extended), and handle edge cases like fewer than 2 days, decreasing prices, or fees larger than any profit.

2. Solve single transaction with one pass

Iterate through prices, tracking the minimum price seen so far and the maximum profit; record buy and sell indices when a new max profit is found.

3. Extend to two transactions with cooldown and fee using DP

Define states: holding (bought but not sold), sold (just sold, must cooldown), and cooldown (ready to buy). Use DP arrays or variables to compute max profit after each day, incorporating the fee at sell and enforcing a one-day cooldown.

4. Prove correctness and analyze complexity

Argue that the DP considers all valid sequences of transactions respecting cooldown and fee, and that the single-transaction solution is a special case. State time O(n) and space O(1) for both.

5. Discuss trade-offs and potential optimizations

Compare DP with alternative approaches like divide-and-conquer for two transactions without cooldown, and explain why DP is preferable with cooldown and fee. Mention that the solution can be adapted to return the actual transaction days if needed.

Key Points to Mention

  • Single transaction: track min price and max profit in one pass, O(n) time and O(1) space.
  • Two transactions with cooldown and fee: state machine with states holding, sold, cooldown; transitions: buy from cooldown, sell to sold (subtract fee), cooldown to cooldown.
  • DP recurrence: hold[i] = max(hold[i-1], cooldown[i-1] - price[i]); sold[i] = hold[i-1] + price[i] - fee; cooldown[i] = max(cooldown[i-1], sold[i-1]).
  • Correctness: DP considers all valid sequences; base cases ensure no invalid transactions.
  • Complexity: O(n) time, O(1) space by using variables instead of arrays.
  • Edge cases: n<2, decreasing prices, fee >= profit, cooldown at boundaries.

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