From e224fbae0c156fee82feb99666004033797ab820 Mon Sep 17 00:00:00 2001 From: robin Date: Mon, 7 Feb 2022 11:59:36 +0800 Subject: [PATCH] :sparkles: que red package --- .../algorithm/leetcode/LeetCode16.java | 74 +++++++++++++++++++ .../algorithm/redpackage/DoubleDivide.java | 48 ++++++++++++ .../redpackage/RandomRedPackage.java | 31 ++++++++ .../redpackage/SegmentRedPackage.java | 61 +++++++++++++++ 4 files changed, 214 insertions(+) create mode 100644 datastructure/src/main/java/org/alis/smallcc/algorithm/leetcode/LeetCode16.java create mode 100644 datastructure/src/main/java/org/alis/smallcc/algorithm/redpackage/DoubleDivide.java create mode 100644 datastructure/src/main/java/org/alis/smallcc/algorithm/redpackage/RandomRedPackage.java create mode 100644 datastructure/src/main/java/org/alis/smallcc/algorithm/redpackage/SegmentRedPackage.java diff --git a/datastructure/src/main/java/org/alis/smallcc/algorithm/leetcode/LeetCode16.java b/datastructure/src/main/java/org/alis/smallcc/algorithm/leetcode/LeetCode16.java new file mode 100644 index 0000000..16fab44 --- /dev/null +++ b/datastructure/src/main/java/org/alis/smallcc/algorithm/leetcode/LeetCode16.java @@ -0,0 +1,74 @@ +package org.alis.smallcc.algorithm.leetcode; + +import java.util.Arrays; +import java.util.concurrent.ThreadLocalRandom; + +/** + * 动态规划 + * house-robber + * 小偷偷钱问题 + * 现在有一个排别墅 小偷可以去偷钱,每一栋别墅里面的钱的数量都不一样,但是没两个邻居之间有报警装置,小偷不能偷挨在一起的别墅,请问最坏的情况下小偷能偷多少 + *

+ * 例如: [1,2,2,4,1,2,3] 小偷偷到的钱= 4+3+2 + * + * @author robin + * @date 2022/1/29 15:35 + */ +public class LeetCode16 { + + private static final Integer[] ARRAY = {3, 1, 5, 7, 9, 11}; + + + public static void main(String[] args) { + // 生成别墅 +// Integer[] array = new Integer[10]; + // 给每个别墅随机加钱 +// for (int i = 0; i < array.length; i++) { +// array[i] = ThreadLocalRandom.current().nextInt(0, 100); +// } + // 打印出别墅的排列 + System.out.println(Arrays.toString(ARRAY)); + // 小偷开始偷钱 + Integer robberies = robberies(ARRAY); + // 小偷一共偷了多少钱 + System.out.println(robberies); + } + + /** + * @param array 数组 + * @return 总金额 + */ + private static Integer robberies(Integer[] array) { + // 小偷偷的钱的总额 + int count = 0; + for (int i = 0; i < array.length; i += 2) { + int max = Math.max(array[i], i < array.length - 1 ? array[i + 1] : array[i]); + System.out.printf("%d + %d = %d%n", count, max, count + max); + count += max; + + } + + return count; + } + + + /** + * 深度优化 + * + * @param array 数组 + * @return 总金额 + */ +// private static Integer robberies(Integer[] array) { +// int a = 0; +// int b = 0; +// +// for (Integer integer : array) { +// int temp = b; +// b = Math.max(a + integer, b); +// System.out.printf("%d + %d = %d%n", a, integer, a + integer); +// a = temp; +// } +// +// return b; +// } +} diff --git a/datastructure/src/main/java/org/alis/smallcc/algorithm/redpackage/DoubleDivide.java b/datastructure/src/main/java/org/alis/smallcc/algorithm/redpackage/DoubleDivide.java new file mode 100644 index 0000000..37a3b01 --- /dev/null +++ b/datastructure/src/main/java/org/alis/smallcc/algorithm/redpackage/DoubleDivide.java @@ -0,0 +1,48 @@ +package org.alis.smallcc.algorithm.redpackage; + +import java.util.Random; +import java.util.concurrent.ThreadLocalRandom; + +/** + * 红包算法只 + * 双倍平均算法 + *

+ * 红包的最小单位是分 所以这里需要执行乘100的倍数 + * + * @author robin + * @date 2022/2/7 10:22 + */ +public class DoubleDivide { + + public static void main(String[] args) { + dividePackage(10000, 10); + } + + + /** + * 双倍算法 + * + * @param total 总金额 + * @param count 总份数 + */ + private static void dividePackage(Integer total, Integer count) { + int temp = count; + int endCount = 0; + int min = 1; + for (int i = 1; i <= temp; i++) { + int amount; + if (i == temp) { + amount = total; + } else { + amount = Math.max(min, ThreadLocalRandom.current().nextInt(total / count * 2 - 1) + 1 - min); + } + total -= amount; + count--; + System.out.printf("第%d 个人抢到了 %f 元%n", i, (float) amount / 100); + endCount += amount; + } + System.out.printf("红包的总数是%d %n", endCount); + } + + +} diff --git a/datastructure/src/main/java/org/alis/smallcc/algorithm/redpackage/RandomRedPackage.java b/datastructure/src/main/java/org/alis/smallcc/algorithm/redpackage/RandomRedPackage.java new file mode 100644 index 0000000..62313ae --- /dev/null +++ b/datastructure/src/main/java/org/alis/smallcc/algorithm/redpackage/RandomRedPackage.java @@ -0,0 +1,31 @@ +package org.alis.smallcc.algorithm.redpackage; + +import java.util.concurrent.ThreadLocalRandom; + +/** + * 随机红包 + * 前几名拿高额钱包一定是最大的 + * + * @author robin + * @date 2022/2/7 10:54 + */ +public class RandomRedPackage { + public static void main(String[] args) { + random(10000, 10); + } + + private static void random(Integer total, Integer count) { + int min = 1; + for (int i = 1; i <= count; i++) { + int amount; + if (i == count) { + amount = total; + } else { + amount = Math.max(min, ThreadLocalRandom.current().nextInt(total - 1) + 1 - min); + } + total -= amount; + System.out.printf("第%d 个人抢到了 %f 元%n", i, (float) amount / 100); + } + } + +} diff --git a/datastructure/src/main/java/org/alis/smallcc/algorithm/redpackage/SegmentRedPackage.java b/datastructure/src/main/java/org/alis/smallcc/algorithm/redpackage/SegmentRedPackage.java new file mode 100644 index 0000000..3bac59d --- /dev/null +++ b/datastructure/src/main/java/org/alis/smallcc/algorithm/redpackage/SegmentRedPackage.java @@ -0,0 +1,61 @@ +package org.alis.smallcc.algorithm.redpackage; + +import java.util.*; +import java.util.stream.Collectors; + +/** + * 分段 + * 线段切割算法 + * + * @author robin + * @date 2022/2/7 11:32 + */ +public class SegmentRedPackage { + + public static void main(String[] args) { + List integers = lineCut(10000, 10); + } + + private static List lineCut(int money, int people) { + + if (money < 1 || people < 1 || money < people) { + return Collections.emptyList(); + } + + List team = new ArrayList<>(people - 1); + List result = new ArrayList<>(people); + + Random random = new Random(); + while (team.size() < people - 1) { + int randomMoney = random.nextInt(money) + 1; + if (!team.contains(randomMoney)) { + team.add(randomMoney); + } + } + + Collections.sort(team); + + System.out.print("分割点:"); + System.out.println(team.stream().map(Integer::floatValue).map(f->f/100).collect(Collectors.toList())); + + int left = 0; + for (Integer integer : team) { + result.add(integer - left); + left = integer; + } + result.add(money - left); + + System.out.print("每人金额:"); + System.out.println(result.stream().map(Integer::floatValue).map(f->f/100).collect(Collectors.toList())); + + // 验证分割后的数是否是输入的总金额 + result.stream().reduce(Integer::sum).ifPresent(amount -> { + System.out.print("总金额:"); + System.out.println(amount); + }); + + return result; + } + + +}