optimal-account-balancing

一群朋友去度假,有时互相借钱。

 

例如,爱丽丝为比尔的午餐支付了 10 美元。后来克里斯给爱丽丝 5 美元搭出租车。我们可以假设每笔交易为一个三元组(X,Y,Z),这意味着第 个人借给第 个人 美元。假设 Alice,Bill 和 Chris 是第0,1,2  个人(0,1,2是他们的ID),他们之间的交易可以表示为[ [ 0,1,10 ],[ 2,0,5 ] ]。

 

给定一组人之间的交易清单,返回结算所需的最低交易数量

九章算法一篇置顶题目 挺有意思 第一次看到这种需要指数级复杂度的面试题

下面的解法非常具有局限性 如果 debt非零的人多于32 或 64 下面的方法是行不通的

 

 

 1 public class Solution {
 2 
 3       public int minTransfer(int[][] transactions){
 4            Map<Integer, Integer> debts = new HashMap<Integer, Integer>();
 5            for(int[] t: transactions){
 6                    debts.put(t[0], getOrDefault(t[0], 0)-t[2]);
 7                    debts.put(t[1], getOrDefault(t[1], 0)+t[2]);
 8            }
 9            int len = 0;
10            int[] account =  new int[debts.size()];
11            for(int total: debts.values()){
12                if(total!=0){
13                   account[len++] = total;
14                }
15            }
16            if(len ==0) return 0;
17            int dp = new int[1<<len];
18            Arrays.fill(dp, Integer.MAX_VALUE);
19            for(int l =1; l <dp.length; l++){
20                    int sum =0;
21                    int count =0;
22                    for(int i=0; i<len;i++){
23                           if((1<<i&l)!=0){
24                                 sum + = account[i];
25                                 count ++;
26                           }
27                    }
28                    if(sum ==0){
29                            dp[l] = count-1;
30                            for(int i =1; i<l;i++){
31                                  if((i&l)==i &&(dp[i]+dp[l-i])< dp[l]){
32                                         dp[l] = dp[i]+dp[l-i];
33                                  }
34                            }
35                    }
36            }
37            return dp[len-1];
38       }
39 
40 }

 

 

原文地址:https://www.cnblogs.com/xinqiwm2010/p/6836295.html