← DRW Interview Insights

DRW·Software Engineer·Online Assessment (OA)·Intermediate

IntermediatePrefer not to say
May 2026Remote

Summary

DRW gave me a 150-minute Codility-style OA with three independent coding problems. Each one had a different flavor: tournament simulation, robot grid coverage, and a digit-mask optimization thing. Felt like a solid filter round, not trivial but also not insane if you know your algorithms.

Questions Asked (7)

Q1

Given n players in a line with distinct skill values forming a permutation, simulate a knockout tournament where adjacent pairs compete each round and the higher-skilled player advances. Return an array b where b[i] is the total number of matches player i participates in.

Algorithms & Data Structures
Author's notes

My first instinct was to track who beats whom explicitly, which got messy fast.

Create a free account to read the full note

AI HintsAI Generated

Suggested Approach

Clarify that the tournament is a balanced binary tree where each round pairs adjacent players, and the winner is the higher skill. Then, for each player, count the number of rounds they survive, which equals the number of matches they play. Use a stack-based approach to find the nearest greater element to the left and right, as a player loses to the first greater element encountered in either direction.

Pro tip: Mention that the number of matches for a player is the minimum of the distances to the nearest greater element on the left and right, but if no greater element exists on one side, use the other side. This insight shows you understand the underlying structure and can optimize to O(n).

1. Understand the tournament structure

Recognize that the tournament is a balanced binary tree where each round pairs adjacent players. The winner advances, so a player's number of matches equals the number of rounds they survive.

2. Identify when a player loses

A player loses when they face a higher-skilled player. Since the tournament is balanced, the first higher-skilled player they encounter will be the nearest greater element to the left or right, whichever is closer.

3. Compute nearest greater elements

Use a monotonic stack to find the nearest greater element to the left and to the right for each player in O(n) time.

4. Calculate matches per player

For each player, the number of matches is the minimum of the distances to the nearest greater element on the left and right. If no greater element exists on one side, use the other side's distance.

5. Handle edge cases and verify

Consider the player with the maximum skill (who wins all matches) and players at the ends. Verify with small examples to ensure correctness.

Key Points to Mention

  • The tournament forms a balanced binary tree where each node represents a match.
  • A player's number of matches equals the number of rounds they survive.
  • The nearest greater element to the left or right determines when a player loses.
  • Monotonic stack can efficiently find nearest greater elements in O(n).
  • The player with the maximum skill plays log2(n) matches (if n is a power of 2) or the height of the tree.
  • Edge cases: n=1, players at boundaries, and non-power-of-2 n.

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

Q2

For the tournament problem above, as a follow-up: instead of counting matches, return for each player the skill value of the opponent who eliminated them (and a sentinel for the champion). How does the simulation change?

Algorithms & Data Structures
Author's notes

Pretty natural extension once you have the simulation working.

Create a free account to read the full note

AI HintsAI Generated

Suggested Approach

Recognize that the tournament simulation structure remains largely the same, but instead of incrementing a match count, you record the loser's opponent's skill at each match. Use a sentinel (e.g., -1) for the champion who is never eliminated. Discuss how to store and return the results, likely as an array or map from player to opponent skill.

Pro tip: Mention that the sentinel value should be chosen carefully to avoid collision with valid skill values (e.g., use -1 if skills are positive). Also, note that the simulation can be done in O(n) time with a queue or stack, and the output can be built during the simulation without extra passes.

1. Clarify input/output and sentinel

Confirm the input format (list of players with skills) and output format (e.g., array of opponent skills or map). Agree on a sentinel value for the champion, such as -1 or null.

2. Adapt simulation data structures

Keep the same tournament simulation (e.g., queue of players). Instead of a match counter, maintain a result array/map to store the eliminator's skill for each eliminated player.

3. Record eliminations during simulation

When two players compete, the winner's skill is recorded as the eliminator for the loser. Update the result structure accordingly.

4. Handle the champion

After the simulation ends, set the champion's entry in the result to the sentinel value.

5. Analyze complexity and edge cases

Discuss time and space complexity (still O(n) time, O(n) space). Consider edge cases like single player, ties, or duplicate skills.

Key Points to Mention

  • The simulation logic (e.g., queue-based) remains unchanged; only the bookkeeping changes.
  • Use a sentinel like -1 for the champion, ensuring it doesn't conflict with valid skill values.
  • Store results in an array indexed by player ID or a hash map for O(1) updates.
  • Time complexity remains O(n) because each match eliminates one player.
  • Space complexity is O(n) for the result structure.
  • Edge cases: single player (champion with sentinel), ties (define winner rule), and duplicate skills (sentinel still distinct).

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

Q3

You control a robot on an R x C grid with walls and floor cells. For five different floor-cell shape variants (rectangular border only, full rectangle, dumbbell, simple path, arbitrary connected region), construct an instruction string of up to 100,000 moves that visits all required cells without stepping on walls.

Algorithms & Data StructuresTechnical Trade-offs
Author's notes

This one surprised me.

Create a free account to read the full note

AI HintsAI Generated

Suggested Approach

Start by clarifying the problem: the robot must visit all required cells (likely all floor cells) without stepping on walls, and the instruction string length is capped at 100,000. For each shape variant, design a tailored traversal strategy that exploits the shape's structure to minimize moves, then verify coverage and wall avoidance. Discuss trade-offs between simplicity (e.g., DFS) and optimality (e.g., Hamiltonian path) given the move limit.

Pro tip: For the arbitrary connected region, a simple DFS traversal may exceed 100,000 moves if the region is large; instead, propose a spanning tree traversal that visits each cell at most twice, or argue that the limit is sufficient for the given constraints. Also, mention that you would test with edge cases like narrow corridors and dead ends.

1. Clarify problem constraints

Confirm the grid size, number of floor cells, and whether 'visits all required cells' means all floor cells or a subset. Ask about the maximum R and C to assess if 100,000 moves is sufficient.

2. Analyze each shape variant

For each shape, identify its structural properties (e.g., rectangular border is a cycle, full rectangle is a grid, dumbbell has two blobs connected by a path) to design an efficient traversal.

3. Design traversal algorithms

Propose specific algorithms: for border, follow the perimeter; for full rectangle, use a snake pattern; for dumbbell, traverse each blob then the connecting path; for simple path, just follow it; for arbitrary region, use DFS or spanning tree traversal.

4. Verify move count and coverage

Estimate the number of moves for each strategy and ensure it is under 100,000. Check that all required cells are visited and no walls are stepped on.

5. Discuss trade-offs and edge cases

Compare strategies for simplicity vs. optimality, and mention how to handle edge cases like disconnected regions (if allowed) or narrow passages that force backtracking.

Key Points to Mention

  • Use of graph traversal algorithms (DFS, BFS) to visit all cells
  • Exploiting shape-specific patterns to minimize moves (e.g., perimeter walk, snake pattern)
  • Move count analysis and ensuring it stays under 100,000
  • Handling walls and avoiding invalid moves
  • Trade-offs between simple backtracking and optimal Hamiltonian path
  • Edge cases: dead ends, narrow corridors, and large grids

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

Q4

For the robot coverage problem, can you guarantee a covering walk strictly shorter than 2(V-1) moves in general, or is that bound tight? What grid configuration forces the maximum length?

Algorithms & Data Structures
Author's notes

Didn't think about this carefully during the OA.

Create a free account to read the full note

AI HintsAI Generated

Suggested Approach

First, clarify the problem: a covering walk on a grid graph with V vertices, starting and ending at the same vertex, that visits every vertex at least once. Then, argue that the bound 2(V-1) is tight in general by constructing a grid configuration that forces the walk to traverse each edge twice, such as a tree-like grid (e.g., a star or a path with branches). Finally, explain that for such configurations, any covering walk must traverse each edge at least twice, leading to a length of 2(V-1).

Pro tip: Mention that the bound is tight for trees, and that any grid containing a spanning tree that is a star (or a path with many leaves) forces the maximum length. This shows you understand the underlying graph theory and can connect it to grid-specific constraints.

1. Clarify the problem and assumptions

Restate the problem: a covering walk on a grid graph with V vertices, starting and ending at the same vertex, visiting all vertices. Confirm that the walk can revisit vertices and edges.

2. Analyze the lower bound

Explain that any covering walk must traverse each edge at least twice if the graph is a tree, because to return to the start, each edge must be traversed an even number of times, and at least once in each direction. Thus, length ≥ 2(V-1).

3. Construct a tight example

Provide a grid configuration that forces the maximum length. For example, a 'comb' grid: a long horizontal path with many vertical 'teeth' of length 1. This is a tree, so any covering walk must traverse each edge twice, achieving exactly 2(V-1).

4. Discuss general grids

Note that for grids with cycles, shorter walks may exist because edges can be traversed once. However, the question asks for a guarantee in general, so the bound is tight because there exist grids (trees) where it cannot be improved.

5. Conclude and summarize

Conclude that the bound 2(V-1) is tight in general, and the maximum length is forced by any grid that is a tree, such as a star or a comb. Emphasize that the bound is achievable and cannot be universally improved.

Key Points to Mention

  • Covering walk must start and end at the same vertex (closed walk).
  • For trees, every edge must be traversed at least twice (once in each direction) to return to start.
  • The bound 2(V-1) is tight because there exist grids (trees) where any covering walk has length exactly 2(V-1).
  • Example of a tight grid: a star graph (center connected to many leaves) or a comb grid.
  • In grids with cycles, shorter walks may exist, but the guarantee is about worst-case.
  • The problem is related to the Chinese Postman Problem on trees.

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

Q5

Given an array of up to 200,000 integers, find two elements with no shared decimal digits (their digit sets are disjoint) that maximize the sum. Return the maximum sum or -1 if no valid pair exists.

Algorithms & Data Structures
Author's notes

The key insight I almost missed: you only care which digits a number contains, not the number itself.

Create a free account to read the full note

AI HintsAI Generated

Suggested Approach

Recognize that the digit set of any number is a subset of {0,...,9}, so there are only 2^10 = 1024 possible digit masks. For each mask, keep the largest number with exactly that mask, then iterate over all pairs of masks that are disjoint and compute the maximum sum. This reduces the problem from O(n^2) to O(n + 2^20) time, which is efficient for n up to 200,000.

Pro tip: Mention that you can further optimize by only considering masks that actually appear in the input, and that you can precompute the maximum value for each mask in a single pass. Also, note that the answer is -1 only if no two numbers have disjoint digit sets, which can be checked by verifying if any valid pair exists.

1. Understand the problem and constraints

Clarify that we need two elements (distinct indices) with disjoint digit sets, maximizing their sum. Note the input size (up to 200,000) and that numbers can be negative? (Assume non-negative? Actually problem says integers, but typically non-negative? We'll assume non-negative for simplicity, but if negative, we need to handle carefully. However, the problem likely expects non-negative integers. We'll proceed with non-negative.)

2. Map each number to a digit mask

For each number, compute a 10-bit mask where bit i is set if digit i appears in the number. For example, 123 has mask with bits 1,2,3 set. This mask uniquely represents the set of digits.

3. Aggregate maximum value per mask

Create an array max_val of size 1024, initialized to -1 (or -infinity). For each number, update max_val[mask] = max(max_val[mask], number). This keeps the largest number for each digit set.

4. Find maximum sum over disjoint mask pairs

Iterate over all pairs of masks (i, j) where i & j == 0 and both max_val[i] and max_val[j] are valid (not -1). Compute sum and track the maximum. To avoid redundant checks, only consider i <= j or use a nested loop over all 1024 masks (about 1 million pairs, which is fine).

5. Return result or -1

If a valid pair is found, return the maximum sum; otherwise, return -1. Also consider edge cases: if there is only one number, or if no two numbers have disjoint digit sets.

Key Points to Mention

  • Bitmask representation of digit sets (10 bits for digits 0-9).
  • Time complexity: O(n + 2^20) which is about 1 million operations, well within limits.
  • Space complexity: O(2^10) = O(1) extra space for the max_val array.
  • Handling of duplicate masks: only the largest number for each mask matters.
  • Edge cases: no valid pair, single element, numbers with same digits, numbers containing all digits (mask 1023).
  • Optimization: precompute list of valid masks to reduce pair iterations.

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

Q6

Generalize the digit-disjoint pair problem to selecting k numbers that are pairwise digit-disjoint with maximum total sum. How does the approach change and what is the complexity?

Algorithms & Data StructuresTechnical Trade-offs
Author's notes

Honestly a hard follow-up to reason about on the spot.

Create a free account to read the full note

AI HintsAI Generated

Suggested Approach

First, restate the original digit-disjoint pair problem and its solution (e.g., bitmask DP over digits). Then explain how to generalize to k numbers: the state must track which digits are used and how many numbers have been selected, leading to a DP over digit masks and count. Finally, analyze the complexity, noting the exponential dependence on the number of digits (10) and the polynomial factor for k and n.

Pro tip: Mention that since there are only 10 digits, the digit mask has at most 2^10 = 1024 states, so the DP is feasible; but for large k, the count dimension adds a factor of k, and if k is large, you might need to consider alternative approaches like maximum weight matching or ILP, though they are overkill for 10 digits.

1. Clarify the problem and assumptions

Confirm that numbers are positive integers, digit-disjoint means no shared digits, and we want to maximize sum of k selected numbers. Ask if k is fixed or variable, and if numbers can be used multiple times.

2. Review the pair case

Explain that for k=2, a common approach is to iterate over all pairs or use DP with bitmask of digits, but for generalization, DP is more scalable.

3. Design DP state for general k

Define DP[mask][j] = maximum sum using j numbers with digit mask mask. Transition by adding a number whose digit mask is disjoint from mask, updating to mask|num_mask and j+1.

4. Analyze complexity

There are 2^10 masks and k+1 counts, so O(k * 2^10 * n) time if we iterate over all numbers for each state, or O(k * 3^10) if we precompute best number per mask and iterate over submasks. Space is O(k * 2^10).

5. Discuss trade-offs and optimizations

Mention that for k up to n, the DP is efficient due to small digit space. If k is large, we might need to consider that the maximum k is limited by the number of disjoint digit sets (at most 10 if each number uses one digit, but numbers can have multiple digits). Also note that if numbers can be negative, we need to handle that.

Key Points to Mention

  • Digit mask representation: each number maps to a 10-bit mask indicating which digits it contains.
  • DP state: dp[mask][j] = max sum using j numbers with combined digit mask mask.
  • Transition: for each number with mask m disjoint from mask, update dp[mask|m][j+1] = max(dp[mask|m][j+1], dp[mask][j] + value).
  • Complexity: O(k * 2^10 * n) time, O(k * 2^10) space; can optimize to O(k * 3^10) by precomputing best value per mask and iterating over submasks.
  • Maximum k is bounded by the number of disjoint digit sets, which is at most 10 if each number uses a single digit, but could be less if numbers use multiple digits.
  • For large k, the DP remains feasible because 2^10 is small, but if k is very large (e.g., > 10), the answer might be limited by digit constraints.

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

Q7

If the digit-disjoint condition were relaxed to allow sharing at most one common digit, how would you adapt the mask-based approach?

Algorithms & Data Structures
Author's notes

Short answer: instead of requiring mask1 & mask2 == 0, you'd check that the popcount of mask1 & mask2 is at most 1.

Create a free account to read the full note

AI HintsAI Generated

Suggested Approach

Explain that the original mask-based approach uses bitmasks to represent sets of digits, and disjointness is checked via bitwise AND. To allow sharing at most one common digit, you need to count the number of common digits (popcount of AND) and ensure it is ≤ 1. Then discuss how this affects the algorithm's logic and complexity, and potential optimizations.

Pro tip: Mention that while the condition change seems minor, it can significantly impact performance because you can no longer rely on fast bitwise AND checks alone; you must compute popcount, which may be more expensive. Also, consider precomputing popcounts for all possible masks if the digit set is small.

1. Review original mask-based approach

Briefly recap how masks represent digit sets and how disjointness is checked using bitwise AND (result == 0).

2. Adapt condition to allow one common digit

Replace the disjointness check with a check that the number of common digits (popcount of AND) is ≤ 1.

3. Analyze impact on algorithm

Discuss how this change affects time complexity, especially if the original algorithm relied on fast bitwise operations. Consider if additional data structures or precomputations are needed.

4. Optimize if necessary

Suggest optimizations such as precomputing popcounts for all masks, using lookup tables, or pruning search space based on the new condition.

5. Test and validate

Emphasize the importance of testing edge cases, such as when masks share exactly one digit or none, and ensuring the new condition is correctly applied.

Key Points to Mention

  • Bitmask representation of digit sets
  • Bitwise AND to find common digits
  • Popcount (population count) to count common digits
  • Condition: popcount(mask1 & mask2) <= 1
  • Potential performance impact and optimizations (e.g., precomputed popcount table)
  • Edge cases: masks with no common digits, exactly one common digit, or multiple common digits

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