465. Optimal Account Balancing
实现splitwise的核心算法,一堆借钱的transaction,问最少需要安排几次还账能让所有人清账。先重新组织数据,把每个人的balance建成一个map。DFS遍历所有可能的还款方式,找出最短让所有balance清0的方式,用排序来跳过效果相同的还款方式作为小优化。还有DP解法是把所有人看成由两个subgrounp拼成的,用二进制encoding所有可能的combination,检查每个subgroup的balance和是否为0,为0意味着该group收支平衡。
class Solution {
public:
/*
* @param edges: a directed graph where each edge is represented by a tuple
* @return: the number of edges
*/
int dfs(vector<int> &debt, int cur, int count) {
const int N = debt.size();
while (cur < N && debt[cur] == 0) ++cur;
if (cur == N) return count;
int res = N;
for (int i = cur + 1; i < N; ++i) {
if ((i > cur + 1 && debt[i] == debt[i - 1]) || (debt[i] * debt[cur] > 0)) continue;
debt[i] += debt[cur];
res = min(res, dfs(debt, cur + 1, count + 1));
debt[i] -= debt[cur];
}
return res;
}
int balanceGraph(vector<vector<int>> &edges) {
unordered_map<int, int> m;
for (const auto &e : edges) {
m[e[0]] -= e[2];
m[e[1]] += e[2];
}
vector<int> debt;
for (const auto &p : m) {
if (p.second != 0) debt.push_back(p.second);
}
sort(debt.begin(), debt.end());
return dfs(debt, 0, 0);
}
};
Last updated
Was this helpful?