Сложность: medium
Дан массив транзакций transactions, где transactions[i] = [fromi, toi, amounti] указывает на то, что человек с ID = fromi дал сумму amounti долларов человеку с ID = toi.
Верните минимальное количество транзакций, необходимых для урегулирования долгов.
Пример:
Input: transactions = [[0,1,10],[2,0,5]]
Output: 2
👨💻 Алгоритм:
1⃣Создать хеш-таблицу для хранения чистого баланса каждого человека.
2⃣Собрать все ненулевые чистые балансы в массив balance_list.
3⃣Определить рекурсивную функцию dfs(cur) для очистки всех балансов в диапазоне balance_list[0 ~ cur]:
Игнорировать cur, если баланс уже равен 0. Пока balance_list[cur] = 0, переходить к следующему человеку, увеличивая cur на 1.
Если cur = n, вернуть 0.
В противном случае установить cost на большое значение, например, inf.
Пройтись по индексу nxt от cur + 1, если balance_list[nxt] * balance_list[cur] < 0,
Добавить баланс balance_list[cur] к balance_list[nxt]: balance_list[nxt] += balance_list[cur].
Рекурсивно вызвать dfs(cur + 1) как dfs(cur) = 1 + dfs(cur + 1).
Убрать ранее переданный баланс от cur: balance_list[nxt] -= balance_list[cur] (откат).
Повторить с шага 5 и отслеживать минимальное количество операций cost = min(cost, 1 + dfs(cur + 1)), найденных в итерации.
Вернуть cost, когда итерация завершена. Вернуть dfs(0).
😎 Решение:
import java.util.*;
public class Solution {
private List<Integer> creditList;
public int minTransfers(int[][] transactions) {
Map<Integer, Integer> creditMap = new HashMap<>();
for (int[] t : transactions) {
creditMap.put(t[0], creditMap.getOrDefault(t[0], 0) + t[2]);
creditMap.put(t[1], creditMap.getOrDefault(t[1], 0) - t[2]);
}
creditList = new ArrayList<>();
for (int amount : creditMap.values()) {
if (amount != 0) {
creditList.add(amount);
}
}
int n = creditList.size();
return dfs(0, n);
}
private int dfs(int cur, int n) {
while (cur < n && creditList.get(cur) == 0) {
cur++;
}
if (cur == n) {
return 0;
}
int cost = Integer.MAX_VALUE;
for (int nxt = cur + 1; nxt < n; nxt++) {
if (creditList.get(nxt) * creditList.get(cur) < 0) {
creditList.set(nxt, creditList.get(nxt) + creditList.get(cur));
cost = Math.min(cost, 1 + dfs(cur + 1, n));
creditList.set(nxt, creditList.get(nxt) - creditList.get(cur));
}
}
return cost;
}
}
Ставь 👍 и забирай 📚 Базу знаний
