You are given an array of transactions transactions where transactions[i] = [fromi, toi, amounti] indicates that the person with ID = fromi gave amounti $ to the person with ID = toi.
Return the minimum number of transactions required to settle the debt.
Example 1:
Input: transactions = [[0,1,10],[2,0,5]] Output: 2 Explanation: Person #0 gave person #1 $10. Person #2 gave person #0 $5. Two transactions are needed. One way to settle the debt is person #1 pays person #0 and #2 $5 each.
Example 2:
Input: transactions = [[0,1,10],[1,0,1],[1,2,5],[2,0,5]] Output: 1 Explanation: Person #0 gave person #1 $10. Person #1 gave person #0 $1. Person #1 gave person #2 $5. Person #2 gave person #0 $5. Therefore, person #1 only need to give person #0 $4, and all debt is settled.
Constraints:
1 <= transactions.length <= 8transactions[i].length == 30 <= fromi, toi < 12fromi != toi1 <= amounti <= 100Problem Overview: You receive a list of transactions between people. Each transaction transfers money from one person to another. The goal is to settle all debts with the minimum number of additional transactions.
The key observation: instead of working with the original transactions, compute each person's net balance. Positive means they should receive money, negative means they owe money. The problem then becomes pairing these balances so that all accounts end at zero using the fewest transfers.
Approach 1: Backtracking on Net Balances (O(n!) time, O(n) space)
First build a balance array using an array. Iterate through transactions and update each person's net balance. Filter out zeros because they are already settled. Then apply backtracking: pick the first non‑zero balance and try settling it with every opposite‑signed balance that appears later in the list. For each pairing, transfer the amount, recurse, and restore the balance (classic DFS with backtracking). Pruning happens when identical balances appear or when a perfect cancellation occurs. This drastically reduces the search space and works well for the typical constraint of ≤12 people with non‑zero balances.
Approach 2: Bitmask Dynamic Programming (O(n * 2^n) time, O(2^n) space)
Another approach uses dynamic programming with bit manipulation. Each bitmask represents a subset of people whose balances we try to settle internally. Compute the total balance of each subset; if it equals zero, that subset can settle with size - 1 transactions. Use DP to combine smaller zero-sum subsets into larger ones and minimize transactions. The state dp[mask] stores the minimum transactions needed for that subset. Iterating over submasks allows merging valid groups efficiently.
The DP formulation transforms the problem into partitioning people into zero-sum groups. Each group requires exactly k - 1 transactions if it contains k people.
Recommended for interviews: Backtracking with balance reduction is the most common interview solution. It shows you understand debt compression and recursive search with pruning. Bitmask DP is more advanced and demonstrates strong skills with subset states and optimization, but many candidates default to the backtracking approach because it is easier to reason about during whiteboard interviews.
Python
Java
C++
Go
TypeScript
| Approach | Time | Space | When to Use |
|---|---|---|---|
| Backtracking on Net Balances | O(n!) worst case | O(n) | Best practical solution for small number of participants (≤12). Common interview approach with pruning. |
| Bitmask Dynamic Programming | O(n * 2^n) | O(2^n) | Useful when modeling subset partitions and zero-sum groups. Demonstrates strong DP and bitmask reasoning. |
Optimal Account Balancing | LeetCode | Splitwise Algorithm | Solution Explained in Detail with Code • Tanishq Chaudhary • 18,662 views views
Watch 9 more video solutions →Practice Optimal Account Balancing with our built-in code editor and test cases.
Practice on FleetCodePractice this problem
Open in Editor