← Grammarly Interview Insights

Grammarly·Software Engineer·Technical Phone Screen·Intermediate

Intermediate
May 2026

Summary

Phone screen at Grammarly for a software engineer role, three binary tree problems back to back. Nothing too wild but the third one had some teeth to it.

Questions Asked (3)

Q1

Given the root of a binary tree, write a function to return its maximum depth (the length of the longest path from root to leaf).

Algorithms & Data Structures
Author's notes

Warmup question, basically.

Create a free account to read the full note

AI HintsAI Generated

Suggested Approach

Start by clarifying the definition of maximum depth and edge cases, then present a recursive DFS solution that computes the depth as 1 + max(depth(left), depth(right)). Discuss the time and space complexity, and optionally mention an iterative BFS alternative.

Pro tip: Show awareness of potential stack overflow in recursion for very deep trees and suggest an iterative approach as a follow-up, demonstrating production-level thinking.

1. Clarify the problem

Confirm that maximum depth is the number of nodes along the longest path from root to leaf, and discuss edge cases like empty tree (depth 0) and single node (depth 1).

2. Choose an approach

Decide between recursive DFS (simpler, elegant) and iterative BFS (avoids recursion limits). Explain your choice based on constraints and clarity.

3. Implement the solution

Write clean code for the chosen approach. For DFS: if root is null return 0; else return 1 + max(maxDepth(left), maxDepth(right)). For BFS: use a queue and count levels.

4. Analyze complexity

State that time complexity is O(n) since each node is visited once, and space complexity is O(h) for DFS (h = height) or O(w) for BFS (w = max width).

5. Test with examples

Walk through a small example (e.g., [3,9,20,null,null,15,7] returns 3) to verify correctness and edge cases.

Key Points to Mention

  • Definition of maximum depth (number of nodes on longest root-to-leaf path)
  • Recursive DFS solution with base case and recurrence relation
  • Time complexity O(n) and space complexity O(h) for recursion stack
  • Iterative BFS alternative using a queue and level counting
  • Handling edge cases: empty tree, skewed tree
  • Trade-offs between recursion and iteration (stack overflow risk)

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

Q2

Given the root of a binary tree, return its level-order traversal as a list of lists, where each inner list contains the values at that depth.

Algorithms & Data Structures
Author's notes

BFS with a queue.

Create a free account to read the full note

AI HintsAI Generated

Suggested Approach

Use an iterative BFS with a queue to process nodes level by level, capturing each level's values before moving to the next. Clearly explain the algorithm, then implement it with attention to edge cases and complexity.

Pro tip: Mention that you can use a sentinel (e.g., null) or track the queue size to separate levels, and note that this approach is easily adaptable to variations like zigzag traversal.

1. Clarify and Confirm

Restate the problem to ensure understanding: return a list of lists where each inner list contains the values at that depth. Ask about edge cases like empty tree or skewed tree.

2. Choose BFS with Queue

Explain that level-order traversal naturally uses BFS. Use a queue to process nodes level by level, and for each level, record the values of all nodes at that depth.

3. Implement with Level Tracking

Initialize a queue with the root. While the queue is not empty, determine the current level size, dequeue that many nodes, collect their values, and enqueue their children. Append the level list to the result.

4. Analyze Complexity

State that time complexity is O(n) since each node is visited once, and space complexity is O(m) where m is the maximum number of nodes at any level (or O(n) in the worst case).

5. Test with Examples

Walk through a simple example (e.g., [3,9,20,null,null,15,7]) to verify the output. Mention edge cases like empty tree (return []) and single node (return [[root.val]]).

Key Points to Mention

  • BFS vs DFS: BFS is more intuitive for level-order, but DFS with level tracking is also possible.
  • Queue implementation: Use a deque or list with index pointer for efficiency.
  • Level separation: Track level size or use a sentinel to distinguish levels.
  • Edge cases: Empty tree, skewed tree, and tree with varying depths.
  • Complexity: O(n) time and O(n) space in worst case.
  • Adaptability: The approach can be modified for zigzag traversal or right-side view.

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

Q3

In a binary tree where each node holds a value from 0 to 25 (representing 'a' to 'z'), find the lexicographically smallest string formed by reading from any leaf up to the root.

Algorithms & Data Structures
Author's notes

This is where I actually had to think.

Create a free account to read the full note

AI HintsAI Generated

Suggested Approach

Use a depth-first search (DFS) to traverse all root-to-leaf paths, constructing the string for each path by prepending the current node's character as you go. Keep track of the lexicographically smallest string found so far, comparing at each leaf. Alternatively, use a recursive function that returns the smallest string from a subtree, combining the current node's character with the smallest child string.

Pro tip: Mention that you can optimize by pruning branches: if the current path's prefix is already lexicographically larger than the best found so far, you can stop exploring that branch. This shows awareness of efficiency beyond the naive approach.

1. Clarify the problem and constraints

Confirm that the string is formed by reading from leaf to root, so the leaf's character is the first character of the string. Discuss edge cases like a single-node tree (root is leaf) and trees with varying depths.

2. Choose a traversal strategy

Decide between top-down DFS (building strings as you go down) or bottom-up recursion (returning smallest string from children). Explain why DFS is suitable since we need to explore all paths.

3. Define the recursive function

For bottom-up: at each node, recursively get the smallest string from left and right subtrees, then prepend the current node's character to the smaller one. For top-down: pass the current string (reversed) and update the global minimum at leaves.

4. Handle base cases and comparisons

At a leaf, the string is just the leaf's character. When comparing strings, use lexicographic order. Ensure that if one subtree is null, you only consider the other.

5. Analyze complexity and potential optimizations

Time complexity is O(N * L) where N is number of nodes and L is max depth (due to string concatenation/comparison). Space is O(H) for recursion stack. Mention pruning or using a trie-like approach for optimization.

Key Points to Mention

  • Depth-first search (DFS) is natural for exploring all root-to-leaf paths.
  • Lexicographic comparison of strings: shorter string is smaller if it is a prefix of the longer one.
  • String concatenation and comparison costs: consider using StringBuilder or similar to avoid O(N^2) in languages like Java.
  • Edge cases: single node tree, skewed tree, multiple leaves with same string.
  • Optimization: pruning branches where the current prefix is already larger than the best found.
  • Alternative approach: convert to a trie of reversed strings and find the smallest leaf-to-root string.

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