A group of friends went on holiday and sometimes lent each other money. For example, Alice paid for Bill's lunch for $10. Then later Chris gave Alice $5 for a taxi ride. We can model each transaction as a tuple (x, y, z) which means person x gave person y $z. Assuming Alice, Bill, and Chris are person 0, 1, and 2 respectively (0, 1, 2 are the person's ID), the transactions can be represented as [[0, 1, 10], [2, 0, 5]].

Given a list of transactions between a group of people, return the minimum number of transactions required to settle the debt.

Note:

  1. A transaction will be given as a tuple (x, y, z). Note that x ≠ y and z > 0.
  2. Person's IDs may not be linear, e.g. we could have the persons 0, 1, 2 or we could also have the persons 0, 2, 6.

Example 1:

Input:
[[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:
[[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.

这道题给了一堆某人欠某人多少钱这样的账单,问经过优化后最少还剩几个。其实就相当于一堆人出去玩,某些人可能帮另一些人垫付过花费,最后结算总花费的时候可能你欠着别人的钱,其他人可能也欠你的欠,需要找出简单的方法把所有欠账都还清就行了。这道题的思路跟之前那道 Evaluate Division 有些像,都需要对一组数据颠倒顺序处理。这里使用一个 HashMap 来建立每个人和其账户的映射,其中账户若为正数,说明其他人欠你钱;如果账户为负数,说明你欠别人钱。对于每份账单,前面的人就在 HashMap 中减去钱数,后面的人在哈希表中加上钱数。这样每个人就都有一个账户了,接下来要做的就是合并账户,看最少需要多少次汇款。先统计出账户值不为0的人数,因为如果为0了,表明你既不欠别人钱,别人也不欠你钱,如果不为0,把钱数放入一个数组 accnt 中,然后调用递归函数。在递归函数中,首先跳过为0的账户,然后看若此时 start 已经是 accnt 数组的长度了,说明所有的账户已经检测完了,用 cnt 来更新结果 res。否则就开始遍历之后的账户,如果当前账户和之前账户的钱数正负不同的话,将前一个账户的钱数加到当前账户上,这很好理解,比如前一个账户钱数是 -5,表示张三欠了别人5块钱,当前账户钱数是5,表示某人欠了李四5块钱,那么张三给李四5块,这两人的账户就都清零了。然后调用递归函数,此时从当前改变过的账户开始找,cnt 表示当前的转账数,需要加1,后面别忘了复原当前账户的值,典型的递归写法,参见代码如下:

class Solution {
public:
int minTransfers(vector<vector<int>>& transactions) {
int res = INT_MAX;
unordered_map<int, int> m;
for (auto t : transactions) {
m[t[]] -= t[];
m[t[]] += t[];
}
vector<int> accnt;
for (auto a : m) {
if (a.second != ) accnt.push_back(a.second);
}
helper(accnt, , , res);
return res;
}
void helper(vector<int>& accnt, int start, int cnt, int& res) {
int n = accnt.size();
while (start < n && accnt[start] == ) ++start;
if (start == n) {
res = min(res, cnt);
return;
}
for (int i = start + ; i < n; ++i) {
if ((accnt[i] < && accnt[start] > ) || (accnt[i] > && accnt[start] < )) {
accnt[i] += accnt[start];
helper(accnt, start + , cnt + , res);
accnt[i] -= accnt[start];
}
}
}
};

Github 同步地址:

https://github.com/grandyang/leetcode/issues/465

类似题目:

Evaluate Division

参考资料:

https://leetcode.com/problems/optimal-account-balancing/

https://leetcode.com/problems/optimal-account-balancing/discuss/95369/share-my-on-npc-solution-tle-for-large-case

https://leetcode.com/problems/optimal-account-balancing/discuss/95355/11-liner-9ms-DFS-solution-(detailed-explanation)

LeetCode All in One 题目讲解汇总(持续更新中...)

[LeetCode] 465. Optimal Account Balancing 最优账户平衡的更多相关文章

  1. [LeetCode] Optimal Account Balancing 最优账户平衡

    A group of friends went on holiday and sometimes lent each other money. For example, Alice paid for ...

  2. LC 465. Optimal Account Balancing 【lock,hard】

    A group of friends went on holiday and sometimes lent each other money. For example, Alice paid for ...

  3. Leetcode: Optimal Account Balancing

    A group of friends went on holiday and sometimes lent each other money. For example, Alice paid for ...

  4. Optimal Flexible Architecture(最优灵活架构)

    来自:Oracle® Database Installation Guide 12_c_ Release 1 (12.1) for Linux Oracle base目录命名规范: /pm/s/u 例 ...

  5. OBST(Optimal Binary Tree最优二叉搜索树)

    二叉搜索树 二叉查找树(Binary Search Tree),(又:二叉搜索树,二叉排序树)它或者是一棵空树,或者是具有下列性质的二叉树: 若它的左子树不空,则左子树上所有结点的值均小于它的根结点的 ...

  6. LeetCode All in One 题目讲解汇总(持续更新中...)

    终于将LeetCode的免费题刷完了,真是漫长的第一遍啊,估计很多题都忘的差不多了,这次开个题目汇总贴,并附上每道题目的解题连接,方便之后查阅吧~ 477 Total Hamming Distance ...

  7. LeetCode All in One题解汇总(持续更新中...)

    突然很想刷刷题,LeetCode是一个不错的选择,忽略了输入输出,更好的突出了算法,省去了不少时间. dalao们发现了任何错误,或是代码无法通过,或是有更好的解法,或是有任何疑问和建议的话,可以在对 ...

  8. All LeetCode Questions List 题目汇总

    All LeetCode Questions List(Part of Answers, still updating) 题目汇总及部分答案(持续更新中) Leetcode problems clas ...

  9. Leetcode problems classified by company 题目按公司分类(Last updated: October 2, 2017)

    All LeetCode Questions List 题目汇总 Sorted by frequency of problems that appear in real interviews. Las ...

随机推荐

  1. HTTP和RPC是现代微服务架构,HTTP和RPC是现代微服务架构

    .NET Core使用gRPC打造服务间通信基础设施   一.什么是RPC rpc(远程过程调用)是一个古老而新颖的名词,他几乎与http协议同时或更早诞生,也是互联网数据传输过程中非常重要的传输机制 ...

  2. LeetCode 142:环形链表 II Linked List Cycle II

    给定一个链表,返回链表开始入环的第一个节点. 如果链表无环,则返回 null. 为了表示给定链表中的环,我们使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始). 如果 pos 是 - ...

  3. 三、ForkJoin分析

    ForkJoin分析 一.ForkJoin ​ ForkJoin是由JDK1.7后提供多线并发处理框架.ForkJoin的框架的基本思想是分而治之.什么是分而治之?分而治之就是将一个复杂的计算,按照设 ...

  4. DAX 第九篇:文本函数

    DAX中用于处理文本的函数,和其他语言很相似. 一,文本连接 文本连接也可以使用操作符 & 来实现,也可以使用函数CONCATENATE来实现: CONCATENATE(<text1&g ...

  5. net core中引用GDAL

    <Project Sdk="Microsoft.NET.Sdk"> <PropertyGroup> <OutputType>Exe</Ou ...

  6. 我的Xamarin开发配置

    我用的的是VS2019 步骤1:打开VS→工具→Android→Android SDK 管理器 安装平台的 Android 9.0-pie下的Android SDK Platform 28 和 Goo ...

  7. Web Api全局预防Xss攻击

    本文转载自https://www.cnblogs.com/ruanyifeng/p/4739807.html.对第二种过滤方法的代码进行了一些修改和注释,记录一下免得以后忘了.已经测试过,应该可以直接 ...

  8. Python itertools 操作迭代对象

    Python 的内建模块itertools提供了很多操作迭代对象的方法 参考链接:https://www.liaoxuefeng.com/wiki/1016959663602400/101778314 ...

  9. 2019 物易云通java面试笔试题 (含面试题解析)

      本人5年开发经验.18年年底开始跑路找工作,在互联网寒冬下成功拿到阿里巴巴.今日头条.物易云通等公司offer,岗位是Java后端开发,因为发展原因最终选择去了物易云通,入职一年时间了,也成为了面 ...

  10. jsonHelper帮助类

    使用前,需引用开源项目类using Newtonsoft.Json 链接:https://pan.baidu.com/s/1htK784XyRCl2XaGGM7RtEg 提取码:gs2n using ...