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. Excel导入遇到的问题An object with the same key already exists in the ObjectStateManager……

    我再导入excel的时候,在本地上是好好的,但是部署之后就不对了. 开始以为是路径可能出错,然后特意跟踪了路径发现没问题, 后面写了很多日志记录发现下面那异常: An object with the ...

  2. Oracle索引知识学习笔记

    目录 一.Oracle索引简介 1.1 索引分类 1.2 索引数据结构 1.3 索引特性 1.4 索引使用注意要点 1.5.索引的缺点 1.6.索引失效 二.索引分类介绍 2.1.位图索引 1.2.函 ...

  3. SourceTree 版本跳过bitbucket注册方法

    1.安装sourcetree时 需要选择 bitbucket账号,这个令人头疼 当然肯定有办法来跳过这一步 2.关闭当前安装界面 进入   C:\Users\Administrator\AppData ...

  4. 现代WEB前端的性能优化

    现代WEB前端的性能优化 前言:这只是一份学习笔记. 什么是WEB前端 潜在的优化点: DNS是否可以通过缓存减少DNS查询时间? 网络请求的过程走最近的网络环境? 相同的静态资源是否可以缓存? 能否 ...

  5. C# 消息队列之 RabbitMQ 基础入门

    Ø  简介 C# 实现消息队列的方式有很多种,比如:MSMQ.RabbitMQ.EQueue 等,本文主要介绍使用 RabbitMQ 实现消息队列的基础入门.包括如下内容: 1.   什么是消息队列? ...

  6. ubuntu18.04.2下编译openjdk9源码

    最近在看<深入理解Java虚拟机 第二版>这本书,上面有关于自己编译OpenJDK源码的内容.自己根据书里的指示去操作,花了三天的时间,重装了好几次Ubuntu(还不知道快照这个功能,好傻 ...

  7. Logstash处理数据用法示例---待完善

    filter { mutate { rename => [ "message", "blog_html" ] copy => { "blo ...

  8. MySQL分析数据运行状态利器【show full processlist】

    原文地址:https://www.cnblogs.com/shihuc/p/8733460.html 今天的主角是: SHOW [FULL] PROCESSLIST show full process ...

  9. C# NPOI Excel

    using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threa ...

  10. python安装扩展”unable to find vcvarsall.bat“的解决办法

    产生原因: python3.4用的是msvs2010编译的,所以python3.4默认只能认出msvs2010以上版本 python2.7用的是msvs2008编译的,所以python2.7默认只能认 ...