Optimal Account Balancing

Minimum transactions to clear all debts — DFS over net balances trying offsetting pairs.

Hard
Time O(n!) Space O(n)
LeetCode
5 min read
backtracking

Problem#

transactions[i] = [from, to, amount]. Return the minimum number of transactions to make everyone net-zero.

Examples#

  • [[0,1,10],[2,0,5]]2

Constraints#

  • 1 <= transactions.length <= 8.

Hints#

Hint 1
Reduce to net balances per person; ignore zeros; DFS pairing each non-zero with a later non-zero.

Approach#

Compute net balance per person. Drop zeros. DFS: pick the first non-zero balances[i]; for each later non-zero of opposite sign, transfer to it (one transaction), recurse, undo. Track min transaction count.

Solution#

Optimal Account Balancing
class Solution {
public:
int minTransfers(vector<vector<int>>& transactions) {
unordered_map<int,long long> bal;
for (auto& t : transactions) {
bal[t[0]] -= t[2];
bal[t[1]] += t[2];
}
vector<long long> nz;
for (auto& [_, v] : bal) if (v != 0) nz.push_back(v);
function<int(int)> dfs = [&](int start) {
while (start < (int)nz.size() && nz[start] == 0) ++start;
if (start == (int)nz.size()) return 0;
int best = INT_MAX;
for (int j = start + 1; j < (int)nz.size(); ++j) {
if (nz[j] * nz[start] < 0) {
nz[j] += nz[start];
best = min(best, 1 + dfs(start + 1));
nz[j] -= nz[start];
}
}
return best;
};
return dfs(0);
}
};

Editorial#

Two reductions: (a) only net balances matter — many transactions collapse to a few signed amounts; (b) zeroing the first non-zero balance via a single transfer to any later opposite-sign person is always part of some optimal solution. DFS over the choice of recipient.

Complexity#

  • Time: O(n!) worst-case, very practical for n ≤ 12.
  • Space: O(n).

Concept revision#

Search ESC

Keyboard shortcuts

Shortcuts are disabled while typing in inputs.