← Palo Interview Insights

Palo·Software Engineer·Onsite - Coding / Algorithms·Intermediate

Intermediate
Jul 2026

Summary

Went through a coding round at Palo for a software engineer role. Three questions, all algorithmic, ranging from pretty standard to genuinely tricky. The expression evaluator one took me longer than I'd like to admit.

Questions Asked (3)

Q1

Given a sorted array of integers and a target value, find the index of the target. Return -1 if it's not there. Expected O(log n) time.

Algorithms & Data Structures
Author's notes

Classic binary search, nothing to say really.

Create a free account to read the full note

AI HintsAI Generated

Suggested Approach

Recognize that the sorted array and O(log n) requirement point directly to binary search. Walk through the algorithm step-by-step, maintaining low and high pointers and narrowing the search space by comparing the middle element to the target. Emphasize edge cases and the importance of correct midpoint calculation to avoid overflow.

Pro tip: Mention using mid = low + (high - low) / 2 instead of (low + high) / 2 to prevent integer overflow, and discuss how you would handle duplicates if the problem required finding the first or last occurrence.

1. Clarify the problem

Confirm assumptions: array is sorted ascending, may contain duplicates, and return any valid index if duplicates exist. Ask about input size and constraints.

2. Choose binary search

Explain that binary search achieves O(log n) by halving the search space each iteration, which is optimal for a sorted array.

3. Outline the algorithm

Initialize low = 0, high = n-1. While low <= high, compute mid, compare arr[mid] with target, and adjust low or high accordingly. Return mid if found, else -1.

4. Handle edge cases

Discuss empty array, single element, target smaller than first or larger than last, and duplicates. Mention overflow-safe midpoint calculation.

5. Analyze complexity

State time complexity O(log n) and space complexity O(1). Optionally mention recursive vs iterative trade-offs.

Key Points to Mention

  • Binary search requires a sorted array and repeatedly divides the search interval in half.
  • Use mid = low + (high - low) / 2 to avoid integer overflow.
  • Loop condition low <= high ensures all elements are checked.
  • Return -1 when the search space is exhausted (low > high).
  • Time complexity O(log n), space complexity O(1) for iterative approach.
  • Duplicates: if multiple occurrences, binary search may return any; to find first/last, modify the algorithm to continue searching.

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

Q2

Design a data structure that supports insert, remove, and getRandom, all in average O(1) time.

Algorithms & Data StructuresSystem Design
Author's notes

This one tripped me up more than I expected for something that sounds simple.

Create a free account to read the full note

AI HintsAI Generated

Suggested Approach

Combine a dynamic array (list) with a hash map that stores each element's index in the array. For insert, append to the array and record the index; for remove, swap the target element with the last element, update the moved element's index, then pop; for getRandom, pick a random index and return the element. This achieves average O(1) for all operations.

Pro tip: Mention that getRandom must be uniformly random and that the swap-with-last trick is key to O(1) removal. Also, clarify handling of duplicates if the data structure allows them.

1. Clarify requirements

Ask whether duplicates are allowed, whether remove is by value or by index, and whether getRandom should return each element with equal probability.

2. Choose data structures

Select an array for O(1) random access and a hash map for O(1) lookup of element indices.

3. Design insert and remove

For insert, append to array and add to map. For remove, swap the target with the last element, update the map for the swapped element, then remove the last element from both array and map.

4. Design getRandom

Generate a random index in the range of the array's size and return the element at that index.

5. Analyze complexity and edge cases

Confirm average O(1) time for all operations and discuss edge cases like removing the last element, removing a non-existent element, and handling duplicates.

Key Points to Mention

  • Use a dynamic array (list) for O(1) random access and a hash map for O(1) index lookup.
  • For removal, swap the target element with the last element, update the moved element's index in the map, then pop the last element.
  • Ensure getRandom is uniform by selecting a random index from the array.
  • Handle duplicates by storing a set of indices for each value in the hash map.
  • Discuss average O(1) time complexity and note that worst-case for hash map operations can be O(n).
  • Consider edge cases: removing the last element, removing a non-existent element, and empty data structure.

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

Q3

Evaluate a math expression given as a string with +, -, *, / operators and non-negative integers. Operator precedence applies. Follow-up: support parentheses.

Algorithms & Data Structures
Author's notes

Spent too long on the base case before even thinking about the follow-up.

Create a free account to read the full note

AI HintsAI Generated

Suggested Approach

Start by clarifying the problem constraints and edge cases, then propose a two-stack (operands and operators) solution that respects operator precedence. For the follow-up, extend the same approach by treating parentheses as triggers to evaluate the current sub-expression, or switch to a recursive descent parser for clarity.

Pro tip: Mention that you can avoid the two-stack approach by using a single stack and evaluating on the fly, but emphasize that the two-stack method is more readable and easier to extend for parentheses. Also, proactively discuss handling division by zero and integer division truncation.

1. Clarify requirements and edge cases

Ask about input format, operator precedence, integer division behavior, and whether parentheses are balanced. Confirm that the expression is valid and contains only non-negative integers.

2. Choose a parsing strategy

Decide between two-stack (operators and operands) or recursive descent. For the base problem, two-stack is straightforward; for parentheses, recursive descent or a stack-based shunting-yard algorithm works well.

3. Implement operator precedence handling

Use a precedence map (e.g., +,-: 1; *,/: 2) and a helper to apply the top operator to the top two operands. When encountering an operator, pop and apply while the stack top has higher or equal precedence.

4. Extend to parentheses (follow-up)

Treat '(' as a push and ')' as a trigger to evaluate until the matching '('. Alternatively, use recursion: when encountering '(', recursively evaluate the sub-expression inside.

5. Test and discuss complexity

Walk through examples like '3+2*2', '(1+(4+5+2)-3)+(6+8)'. Mention O(n) time and O(n) space, and note that the solution handles nested parentheses.

Key Points to Mention

  • Operator precedence rules and how to enforce them with a precedence map.
  • Two-stack approach: one for operands, one for operators.
  • Handling parentheses by evaluating sub-expressions when a closing parenthesis is encountered.
  • Edge cases: division by zero, integer division truncation, and multi-digit numbers.
  • Time and space complexity: O(n) time and O(n) space.
  • Alternative approaches: recursive descent parser or shunting-yard algorithm.

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