Aggregate expenses by person, trip, and category
Company: Rippling
Role: Software Engineer
Category: Coding & Algorithms
Difficulty: medium
Interview Round: Onsite
Quick Answer: This question evaluates a candidate's ability to perform efficient data aggregation, use associative data structures (maps/dictionaries), and reason about time and space complexity when processing large collections of records.
Part 1: Aggregate Total Expenses Per Employee
Constraints
- 0 <= len(records) <= 10^6
- Each record has exactly 4 fields: (employee_id, trip_id, category, amount)
- employee_id, trip_id, and category are strings
- 0 <= amount <= 10^9
Examples
Input: ([('E1', 'T1', 'MEAL', 50), ('E2', 'T2', 'HOTEL', 120), ('E1', 'T3', 'TRANSPORT', 30), ('E2', 'T2', 'MEAL', 20)],)
Expected Output: {'E1': 80, 'E2': 140}
Explanation: E1 has 50 + 30 = 80. E2 has 120 + 20 = 140.
Input: ([],)
Expected Output: {}
Explanation: Edge case: no expense records means no totals.
Input: ([('EMP42', 'TRIP9', 'HOTEL', 300)],)
Expected Output: {'EMP42': 300}
Explanation: Single record for one employee.
Input: ([('A', 'T1', 'MEAL', 0), ('A', 'T2', 'HOTEL', 10), ('B', 'T3', 'TRANSPORT', 5), ('A', 'T1', 'MEAL', 15)],)
Expected Output: {'A': 25, 'B': 5}
Explanation: A has 0 + 10 + 15 = 25. B has 5.
Solution
def solution(records):
totals = {}
for employee_id, trip_id, category, amount in records:
totals[employee_id] = totals.get(employee_id, 0) + amount
return totals
Time complexity: O(n), where n is the number of expense records.. Space complexity: O(u), where u is the number of unique employees..
Hints
- A hash map/dictionary is a natural way to accumulate totals by employee_id.
- You only need to scan the records once.
Part 2: Aggregate Expenses Per Trip for One Employee
Constraints
- 0 <= len(records) <= 10^6
- Each record has exactly 4 fields: (employee_id, trip_id, category, amount)
- employee_id, trip_id, and category are strings
- 0 <= amount <= 10^9
Examples
Input: ([('E1', 'T1', 'MEAL', 50), ('E1', 'T1', 'HOTEL', 70), ('E1', 'T2', 'TRANSPORT', 30), ('E2', 'T1', 'MEAL', 10)], 'E1')
Expected Output: {'T1': 120, 'T2': 30}
Explanation: For E1, trip T1 has 50 + 70 = 120, and T2 has 30.
Input: ([('E2', 'T1', 'MEAL', 10)], 'E1')
Expected Output: {}
Explanation: Edge case: the target employee has no matching records.
Input: ([], 'E1')
Expected Output: {}
Explanation: Edge case: empty record list.
Input: ([('E3', 'ONLY', 'MEAL', 0)], 'E3')
Expected Output: {'ONLY': 0}
Explanation: A single matching record with amount 0 should still appear in the result.
Solution
def solution(records, employee_id):
totals = {}
for emp_id, trip_id, category, amount in records:
if emp_id == employee_id:
totals[trip_id] = totals.get(trip_id, 0) + amount
return totals
Time complexity: O(n), where n is the number of expense records.. Space complexity: O(t), where t is the number of trips for the target employee..
Hints
- Ignore records whose employee_id does not match the target.
- For matching records, accumulate amounts using trip_id as the dictionary key.
Part 3: Aggregate Expenses Per Category for One Employee
Constraints
- 0 <= len(records) <= 10^6
- Each record has exactly 4 fields: (employee_id, trip_id, category, amount)
- employee_id, trip_id, and category are strings
- 0 <= amount <= 10^9
Examples
Input: ([('E1', 'T1', 'MEAL', 50), ('E1', 'T2', 'MEAL', 20), ('E1', 'T2', 'HOTEL', 100), ('E2', 'T1', 'MEAL', 999), ('E1', 'T3', 'TRANSPORT', 30)], 'E1')
Expected Output: {'MEAL': 70, 'HOTEL': 100, 'TRANSPORT': 30}
Explanation: For E1, MEAL is 50 + 20, HOTEL is 100, and TRANSPORT is 30.
Input: ([('E2', 'T1', 'MEAL', 10)], 'E1')
Expected Output: {}
Explanation: Edge case: the target employee has no matching records.
Input: ([], 'E1')
Expected Output: {}
Explanation: Edge case: empty record list.
Input: ([('A', 'T1', 'MEAL', 0), ('A', 'T2', 'MEAL', 15), ('A', 'T3', 'MEAL', 5)], 'A')
Expected Output: {'MEAL': 20}
Explanation: All matching records are in the same category, including a zero amount.
Solution
def solution(records, employee_id):
totals = {}
for emp_id, trip_id, category, amount in records:
if emp_id == employee_id:
totals[category] = totals.get(category, 0) + amount
return totals
Time complexity: O(n), where n is the number of expense records.. Space complexity: O(c), where c is the number of categories used by the target employee..
Hints
- You do not need to group by trip here; only by category.
- A single pass with a dictionary is enough.