Optimal Account Balancing in C++


Suppose a group of friends went on holiday and sometimes they lent each other money. So as an example, Amit paid for Bikram's lunch for $10. Then later Chandan gave Amit $5 for a taxi fare. We have to design a model where each transaction is taken as a tuple (x, y, z) which means person x gave person y $z.

Assuming Amit, Bikram, and Chandan are person 0, 1, and 2 respectively the transactions can be represented as [[0, 1, 10], [2, 0, 5]]. If we have a list of transactions between a group of people, we have to find the minimum number of transactions required to settle the debt.

So, if the input is like [[0,1,10], [2,0,5]], then the output will be 2, as person #0 gave person #1 $10. Then person #2 gave person #0 $5. Here two transactions are needed. One way to settle the debt is person #1 pays person #0 and #2 $5 each.

To solve this, we will follow these steps −

  • Define an array v

  • Define a function dfs(), this will take idx,

  • ret := inf

  • while (idx < size of v and not v[idx] is non-zero), do −

    • (increase idx by 1)

  • for initialize i := idx + 1, when i − size of v, update (increase i by 1), do −

    • if v[i] * v[idx] < 0, then −

      • v[i] := v[i] + v[idx]

      • ret := minimum of ret and 1 + dfs(idx + 1)

      • v[i] := v[i] - v[idx]

  • return (if ret is same as inf, then 0, otherwise ret)

  • From the main method do the following −

  • Define one map m

  • n := size of t

  • for initialize i := 0, when i < n, update (increase i by 1), do −

    • u := t[i, 0], v := t[i, 1]

    • bal := t[i, 2]

    • m[u] := m[u] + bal

    • m[v] := m[v] - bal

  • for each key-value pair i in m, do −

    • if value of i, then −

      • insert value of i at the end of v

    • (increase i by 1)

  • return minimum of dfs(0) and size of v

Example  

Let us see the following implementation to get better understanding −

 Live Demo

#include <bits/stdc++.h>
using namespace std;
class Solution {
public:
   vector<int> v;
   int dfs(int idx) {
      int ret = INT_MAX;
      while (idx < v.size() && !v[idx])
         idx++;
      for (int i = idx + 1; i < v.size(); i++) {
         if (v[i] * v[idx] < 0) {
            v[i] += v[idx];
            ret = min(ret, 1 + dfs(idx + 1));
            v[i] -= v[idx];
         }
      }
      return ret == INT_MAX ? 0 : ret;
   }
   int minTransfers(vector<vector<int>>&t) {
      map<int, int> m;
      int n = t.size();
      for (int i = 0; i < n; i++) {
         int u = t[i][0];
         int v = t[i][1];
         int bal = t[i][2];
         m[u] += bal;
         m[v] -= bal;
      }
      map<int, int>::iterator i = m.begin();
      while (i != m.end()) {
         if (i->second)
            v.push_back(i->second);
         i++;
      }
      return min(dfs(0), (int)v.size());
   }
};
main() {
   Solution ob;
   vector<vector<int>> v = {{0,1,10},{2,0,5}};
   cout << (ob.minTransfers(v));
}

Input

{{0,1,10},{2,0,5}}

Output

2

Updated on: 21-Jul-2020

347 Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements