The problem can be accessed from this link https://leetcode.com/problems/optimal-account-balancing/
*** Didn't realize this was only accessible by premium members, here is the problem statement and examples***
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 <= 8
transactions[i].length == 3
0 <= fromi, toi < 12
fromi != toi
1 <= amounti <= 100
Questions
The first thing is, I am trying to understand how the dp function inside works. I don't use use bitwise operation too much but am vaguely familiar with what shifting, ^(Xor), and mask does but in this example, I'm having a hard time of putting them together.
Secondly, maybe I'll have a better idea once I understand the first problem. However if you could shed some light on what it's memoizing, the time complexity, and how that is more optimal, that would be awesome.
Thirdly, I have come up with my solution to this problem which is at the bottom of this post. I used plain backtracking but when it comes to analyzing the time complexity, I am slightly uncertain. My intuition is that since for loop inside the 'backtrack' function is going from 0 -> len(balance) then 1-> len(balance) ... so it'd be O(n^2)? (if we assume n = len(balance)). Correct me if I am wrong.
Truly thank you for your help in advance.
class Solution:
def minTransfers(self, T: List[List[int]]) -> int:
p = [0] * 12
for f,t,a in T:
p[f] -= a
p[t] += a
arr = []
for a in p:
if a != 0:
arr.append(a)
memo = {}
def dp(count, cur, mask):
nonlocal memo
if (count, cur, mask) in memo:
return memo[(count, cur, mask)]
if mask == 0:
return 0
res = inf
for i in range(len(arr)):
if (1<<i)&mask:
if cur+arr[i]==0:
res = min(res, dp(0, 0, (1<<i)^mask)+count)
else:
res = min(res, dp(count+1, cur+arr[i], (1<<i)^mask))
memo[(count, cur, mask)] = res
return res
mask = (1<<len(arr))-1
return dp(0,0,mask)
My solution
class Solution:
def minTransfers(self, transactions: List[List[int]]) -> int:
# hash person giving and receiving money
map = {}
for i in transactions:
map[i[0]] = map.get(i[0],0)-i[2]
map[i[1]] = map.get(i[1],0)+i[2]
balance = []
for key,val in map.items():
if val != 0:
balance.append(val)
def backtrack(idx):
if idx == len(balance):
return 0
if balance[idx] == 0:
return backtrack(idx+1)
result = float('inf')
for curr in range(idx+1,len(balance)):
if balance[idx]*balance[curr] < 0:
balance[curr]+= balance[idx]
result = min(result,1+backtrack(idx+1))
balance[curr]-= balance[idx]
return result
return backtrack(0)