|
| 1 | +package pp.arithmetic.LCP; |
| 2 | + |
| 3 | +import pp.arithmetic.Util; |
| 4 | + |
| 5 | +import java.util.ArrayList; |
| 6 | +import java.util.List; |
| 7 | + |
| 8 | +/** |
| 9 | + * Created by wangpeng on 2019-10-11. |
| 10 | + * |
| 11 | + * 力扣决定给一个刷题团队发LeetCoin作为奖励。同时,为了监控给大家发了多少LeetCoin,力扣有时候也会进行查询。 |
| 12 | + * |
| 13 | + * |
| 14 | + * |
| 15 | + * 该刷题团队的管理模式可以用一棵树表示: |
| 16 | + * |
| 17 | + * 团队只有一个负责人,编号为1。除了该负责人外,每个人有且仅有一个领导(负责人没有领导); |
| 18 | + * 不存在循环管理的情况,如A管理B,B管理C,C管理A。 |
| 19 | + * |
| 20 | + * |
| 21 | + * 力扣想进行的操作有以下三种: |
| 22 | + * |
| 23 | + * 给团队的一个成员(也可以是负责人)发一定数量的LeetCoin; |
| 24 | + * 给团队的一个成员(也可以是负责人),以及他/她管理的所有人(即他/她的下属、他/她下属的下属,……),发一定数量的LeetCoin; |
| 25 | + * 查询某一个成员(也可以是负责人),以及他/她管理的所有人被发到的LeetCoin之和。 |
| 26 | + * |
| 27 | + * |
| 28 | + * 输入: |
| 29 | + * |
| 30 | + * N表示团队成员的个数(编号为1~N,负责人为1); |
| 31 | + * leadership是大小为(N - 1) * 2的二维数组,其中每个元素[a, b]代表b是a的下属; |
| 32 | + * operations是一个长度为Q的二维数组,代表以时间排序的操作,格式如下: |
| 33 | + * operations[i][0] = 1: 代表第一种操作,operations[i][1]代表成员的编号,operations[i][2]代表LeetCoin的数量; |
| 34 | + * operations[i][0] = 2: 代表第二种操作,operations[i][1]代表成员的编号,operations[i][2]代表LeetCoin的数量; |
| 35 | + * operations[i][0] = 3: 代表第三种操作,operations[i][1]代表成员的编号; |
| 36 | + * 输出: |
| 37 | + * |
| 38 | + * 返回一个数组,数组里是每次查询的返回值(发LeetCoin的操作不需要任何返回值)。由于发的LeetCoin很多,请把每次查询的结果模1e9+7 (1000000007)。 |
| 39 | + * |
| 40 | + * |
| 41 | + * |
| 42 | + * 示例 1: |
| 43 | + * |
| 44 | + * 输入:N = 6, leadership = [[1, 2], [1, 6], [2, 3], [2, 5], [1, 4]], operations = [[1, 1, 500], [2, 2, 50], [3, 1], [2, 6, 15], [3, 1]] |
| 45 | + * 输出:[650, 665] |
| 46 | + * 解释:团队的管理关系见下图。 |
| 47 | + * 第一次查询时,每个成员得到的LeetCoin的数量分别为(按编号顺序):500, 50, 50, 0, 50, 0; |
| 48 | + * 第二次查询时,每个成员得到的LeetCoin的数量分别为(按编号顺序):500, 50, 50, 0, 50, 15. |
| 49 | + * |
| 50 | + * |
| 51 | + * <image src="https://assets.leetcode-cn.com/aliyun-lc-upload/uploads/2019/09/09/coin_example_1.jpg" /> |
| 52 | + * |
| 53 | + * 限制: |
| 54 | + * |
| 55 | + * 1 <= N <= 50000 |
| 56 | + * 1 <= Q <= 50000 |
| 57 | + * operations[i][0] != 3 时,1 <= operations[i][2] <= 5000 |
| 58 | + * |
| 59 | + * 来源:力扣(LeetCode) |
| 60 | + * 链接:https://leetcode-cn.com/problems/coin-bonus |
| 61 | + * 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。 |
| 62 | + */ |
| 63 | +public class _5_bonus { |
| 64 | + |
| 65 | + public static void main(String[] args) { |
| 66 | + _5_bonus bonus = new _5_bonus(); |
| 67 | + Util.printArray(bonus.bonus(6, new int[][]{{1, 2}, {1, 6}, {2, 3}, {2, 5}, {1, 4}}, new int[][]{{1, 1, 500}, {2, 2, 50}, {3, 1}, {2, 6, 15}, {3, 1}})); |
| 68 | + } |
| 69 | + |
| 70 | + /** |
| 71 | + * 解题思路: |
| 72 | + * 1、构建树及依赖关系 |
| 73 | + * 2、按操作赋值 |
| 74 | + * 3、保存取值结果 |
| 75 | + * |
| 76 | + * 提交超时:testCase :https://leetcode-cn.com/submissions/detail/32797078/ |
| 77 | + * |
| 78 | + * @param n |
| 79 | + * @param leadership |
| 80 | + * @param operations |
| 81 | + * @return |
| 82 | + */ |
| 83 | + public int[] bonus(int n, int[][] leadership, int[][] operations) { |
| 84 | + List<Integer> retList = new ArrayList<>(); |
| 85 | + //创建树 |
| 86 | + CoinTree[] trees = new CoinTree[n + 1]; |
| 87 | + for (int i = 1; i <= n; i++) { |
| 88 | + trees[i] = new CoinTree(i); |
| 89 | + } |
| 90 | + //构造依赖关系 |
| 91 | + for (int i = 0; i < leadership.length; i++) { |
| 92 | + int[] item = leadership[i]; |
| 93 | + trees[item[0]].child.add(trees[item[1]]); |
| 94 | + } |
| 95 | + //操作 |
| 96 | + for (int i = 0; i < operations.length; i++) { |
| 97 | + int[] item = operations[i]; |
| 98 | + //操作类型 |
| 99 | + int operation = item[0]; |
| 100 | + switch (operation){ |
| 101 | + case 1://给某个人发币 |
| 102 | + addPersonCoin(trees[item[1]],item[2]); |
| 103 | + break; |
| 104 | + case 2://给某个人和他的团队发币 |
| 105 | + addTeamCoin(trees[item[1]],item[2]); |
| 106 | + break; |
| 107 | + case 3://计算某个人和他的团队币总和,并记录返回 |
| 108 | + retList.add(getTeamCoin(trees[item[1]])); |
| 109 | + break; |
| 110 | + } |
| 111 | + } |
| 112 | + |
| 113 | + //list to array |
| 114 | + int[] retArr = new int[retList.size()]; |
| 115 | + for (int i = 0; i < retList.size(); i++) { |
| 116 | + retArr[i] = retList.get(i); |
| 117 | + } |
| 118 | + |
| 119 | + return retArr; |
| 120 | + } |
| 121 | + |
| 122 | + private int getTeamCoin(CoinTree tree){ |
| 123 | + int result = tree.coinCount; |
| 124 | + for (int i = 0; i < tree.child.size(); i++) { |
| 125 | + result+=getTeamCoin(tree.child.get(i)); |
| 126 | + } |
| 127 | + return result; |
| 128 | + } |
| 129 | + |
| 130 | + private void addPersonCoin(CoinTree tree, int coin) { |
| 131 | + tree.coinCount+=coin; |
| 132 | + } |
| 133 | + |
| 134 | + private void addTeamCoin(CoinTree tree, int coin) { |
| 135 | + addPersonCoin(tree,coin); |
| 136 | + for (int i = 0; i < tree.child.size(); i++) { |
| 137 | + addTeamCoin(tree.child.get(i),coin); |
| 138 | + } |
| 139 | + } |
| 140 | + |
| 141 | + class CoinTree{ |
| 142 | + int value; |
| 143 | + List<CoinTree> child; |
| 144 | + int coinCount = 0; |
| 145 | + |
| 146 | + public CoinTree(int value){ |
| 147 | + this.value = value; |
| 148 | + child = new ArrayList<>(); |
| 149 | + } |
| 150 | + } |
| 151 | +} |
0 commit comments