← Ziphq Interview Insights

Ziphq·Software Engineer·Technical Phone Screen·Intermediate

Intermediate
May 2026

Summary

ZipHQ software engineer round that was basically one coding problem with a follow-up. Pretty focused, no fluff, just tree/graph traversal dressed up as a product-ish data model.

Questions Asked (2)

Q1

You have a list of block objects, each with an id and an optional parentId. Write a function that returns all root block ids, where a root is any block whose parentId is null or references a parent that doesn't exist in the collection.

Algorithms & Data Structures
Author's notes

Not too bad once you realize it's just a set lookup.

Create a free account to read the full note

AI HintsAI Generated

Suggested Approach

Start by clarifying the input format and edge cases, then propose a solution that builds a set of all existing ids and checks each block's parentId against that set. Emphasize that this approach is O(n) time and space, and discuss potential optimizations or alternative data structures.

Pro tip: Mention that you would handle duplicate ids gracefully (e.g., by using a set) and that you would consider the case where a block's parentId references itself, which should not be considered a root.

1. Clarify requirements and edge cases

Ask about the input format (array of objects), whether ids are unique, and how to handle null or missing parents. Confirm that a root is defined as parentId null or not in the set of existing ids.

2. Design the algorithm

Propose building a set of all existing ids for O(1) lookups. Then iterate through the blocks and collect those whose parentId is null or not in the set.

3. Analyze complexity and trade-offs

State that the time complexity is O(n) and space complexity is O(n) due to the set. Discuss if sorting or other structures could help, but note that this is optimal for unsorted input.

4. Handle edge cases and write code

Consider empty input, duplicate ids, self-referencing parentId, and missing parentId property. Write clean code with meaningful variable names and comments.

5. Test and verify

Walk through a few test cases: normal case, missing parent, null parent, empty list, and duplicate ids. Ensure the output matches expectations.

Key Points to Mention

  • Use a hash set for O(1) membership checks to achieve O(n) time complexity.
  • Clarify that a root is defined as parentId being null or referencing a non-existent id.
  • Handle edge cases: empty input, duplicate ids, self-referencing parentId, and missing parentId property.
  • Discuss space-time trade-off: the set uses O(n) extra space, which is acceptable.
  • Consider if the input can be modified or if additional data structures are needed.
  • Mention that the order of root ids in the output may not matter unless specified.

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

Q2

Follow-up: given a specific block id, return the full path of ids from the root down to that block. Walk through your approach, the data structures involved, and the time and space complexity.

Algorithms & Data StructuresTechnical Trade-offs
Author's notes

This is where I stumbled a bit.

Create a free account to read the full note

AI HintsAI Generated

Suggested Approach

Clarify the data structure representing the block hierarchy (e.g., parent pointers or adjacency list) and then propose an algorithm that traces from the target block up to the root, reversing the path. Discuss time and space complexity, and mention trade-offs between different representations.

Pro tip: Always ask about the expected frequency of queries and updates; if queries are frequent, precomputing paths or using a parent pointer with path compression can be more efficient. Also, consider edge cases like invalid block IDs or cycles.

1. Clarify the data model

Ask how the block hierarchy is stored: parent pointers, adjacency list, or a tree structure. Confirm if it's a tree (single parent) or a DAG, and whether block IDs are unique.

2. Choose the traversal strategy

If parent pointers exist, walk upward from the target to the root, collecting IDs, then reverse. If only children lists, perform DFS from root to target, tracking the path.

3. Handle edge cases

Consider invalid block ID, root block (path is just itself), and cycles (if not a tree). Discuss error handling and assumptions.

4. Analyze complexity

For upward traversal: O(d) time and O(d) space, where d is depth. For DFS: O(n) time and O(d) space in worst case. Mention that if many queries, precomputing paths or using binary lifting can reduce query time.

5. Discuss trade-offs and optimizations

Compare parent pointers vs. adjacency list: parent pointers give O(d) query but require updates if tree changes; adjacency list may need O(n) traversal. Suggest caching or memoization if queries are repeated.

Key Points to Mention

  • Assumption of a tree structure with unique block IDs and a single root.
  • Use of parent pointers for efficient upward traversal (O(d) time).
  • Alternative: DFS from root with path tracking (O(n) time, O(d) space).
  • Edge cases: invalid ID, root block, cycles (if not a tree).
  • Complexity analysis: time and space in terms of depth (d) or number of nodes (n).
  • Trade-offs: query performance vs. update cost, and potential optimizations like caching or binary lifting.

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