日前接到阿里一通面试电话。
有一题较为有趣,所以直接收录了下来。
需求:参照微信、支付宝红包,将金额拆分为相应人数的红包,且每个红包不得超过总金额的90%。(由于都是在电话里口述,不知道有没有听错需求,姑且就当它是正确的吧)
由于该需求会产生较多0.01的红包,但是暂且不论红包金额的算法,只论生成红包这段代码是否有错,望大神提点。
package com.demo; import java.math.BigDecimal; import java.util.Random; public class Demo { /** * 单元测试 */ @org.junit.Test public void testSplitRedPacket() throws Exception { long startTime = System.currentTimeMillis(); int sum = 0; BigDecimal amount; int pCount = 2; for (double i = 1; i < 10;) { sum = 0; amount = new BigDecimal(String.valueOf(i)); int amountInt = amount.multiply(new BigDecimal("100")).intValue(); int[] packets = splitRedPacket(amountInt, pCount); for (int packet : packets) { sum += packet; } BigDecimal bSum = new BigDecimal(Double.valueOf(sum / 100.0)); assertCompare(bSum, amount); if(pCount < 20) { pCount++; } else { pCount = 2; } i = new BigDecimal(String.valueOf(i)).add(new BigDecimal("0.1")).doubleValue(); } long endTime = System.currentTimeMillis(); System.out.println("总消耗时间:" + (endTime - startTime) + "毫秒"); } private void assertCompare(BigDecimal sum, BigDecimal amount) { // System.out.println(sum.doubleValue() + " " + amount.doubleValue()); if(sum.doubleValue() != amount.doubleValue()) { throw new RuntimeException("拆分后总金额不相等,计算出错\nbd1=" + sum.doubleValue() + " bd2=" + amount.doubleValue()); } } /** * 拆分红包 * * @param amount 总金额 * @param pCount 人数 * @return * @throws Exception */ public int[] splitRedPacket(int amount, int pCount) throws Exception { // 总金额 /* * TODO 总金额直接使用分计算 */ // 先将总金额单位改为分 int amountInt = amount; // 验证最小红包金额 verifyMinPacket(amountInt, pCount); int[] redPackets = new int[ pCount ]; Random r = new Random(System.nanoTime()); // 最大红包金额 int max = amountInt; // 已发放总金额 int sum = 0; // 每份的金额 int part = 0; for (int i = 0; i < pCount - 1; i++) { // 预留金额 int preAmount = preAmount(max, amountInt, pCount - i - 1); max -= preAmount; part = r.nextInt(max) + 1; // 余额 max -= part; // 补偿预留金额 max += preAmount; sum += part; // BigDecimal bPart = new BigDecimal(Double.valueOf(part / 100.0)); redPackets[i] = part; } // 最后一份红包 // redPackets[pCount - 1] = new BigDecimal(Double.valueOf((amountInt - sum) / 100.0)); redPackets[pCount - 1] = amountInt - sum; return redPackets; } /** * 计算预留金额 * * @param balance 余额 * @param amount 总金额 * @param pCount 剩余人数 * @return */ private int preAmount(int balance, int amount, int pCount) { // 打9折 int $9 = (int) (amount * 0.9); if(balance > $9) { // 余额必须大于总金额的90% 并且 10%足够剩余人数分 int $1 = (int) (amount * 0.1); if($1 / pCount >= 1) { return $1; } else { // 10%不够分的时候 return pCount; } } return pCount; } /** * 验证最小红包金额 * * @param amount 总金额 * @param pCount 人数 * @return * @throws Exception */ private boolean verifyMinPacket(int amount, int pCount) throws Exception { if(amount / pCount >= 1) { return true; } throw new Exception("单个红包不能小于0.01"); } }
相关推荐
### os论文 关于阿里面试题的解析 #### 一、问题背景与初步分析 本篇文章主要探讨了一道来自阿里巴巴的面试题目,该题目涉及到C语言的递归函数及其运行时间的分析。题目给出的递归函数如下: ```c int f(int x){ ...
总结起来,本文介绍了进程创建的基本概念,特别是`fork()`函数的工作方式,以及正则表达式的使用和匹配规则,同时涉及了一道逻辑推理题。对于研发面试来说,这些知识点涵盖了操作系统、编程基础和逻辑思维能力,都是...
【阿里技术面试题解析】 1. **SynchronousQueue Quiz** SynchronousQueue 是一个特殊的 BlockingQueue,它不存储任何元素,所有的插入操作必须等到其他线程进行相应的删除操作才能完成。在给定的代码中,试图向空...
在IT行业中,面试是每个求职者必经的重要环节,尤其是对于目标锁定在知名大厂的求职者来说,准备充分的面试至关...同时,对比不同公司的面试题,还可以了解各家公司对人才的不同需求和偏好,进一步优化自己的面试策略。
以下是针对这些面试题的详细解析: 1. 找到指定坐标的结构:对于这个问题,可以考虑使用哈希表,将每个结构的坐标作为键,结构本身作为值,这样可以实现常数时间内的查找。 2. 求未出现的数:可以使用布隆过滤器,...
这本书不仅提供了解题思路,还对每一道题目的不同解法进行了详尽的解析,有的题目甚至给出了多种解法,帮助读者开阔思维,理解算法的多样性。通过这些内容的学习,读者能够提升解决实际问题的能力,增加面试成功的...
阿里巴巴面试题leetcode CharSimpleAlgorithm 字符串算法 WordConversion 该类是用于改变字母的大小写,使一...ps:该类的实际意义没有想到,是我在浏览LeetCode评论区的时候看到的一道阿里巴巴面试题,所以就实现了一下
今天跟大家分享一道阿里的算法面试题。 题目描述 给定一个正整数nnn,把它拆分为若干个数的和,记这若干个数的积为MMM,求MMM的最大值。 题目分析 这道题正常的思路是使用动态规划算法。 假设 dp[n]dp[n]dp[n] 为正...
以下是对类实例化顺序的详细讲解,以及阿里巴巴笔试题的解析。 首先,类加载分为三个主要阶段:加载、链接和初始化。 1. **加载**:这是类被首次引用时,JVM会尝试从类路径中找到对应的`.class`文件,并将其加载到...
这段C语言代码是一道经典的面试题,主要考察的是对指针和循环的理解。题目中提到“答案是无限循环”,这提示我们代码中可能存在一个没有明确退出条件的循环结构。让我们来详细分析一下。 首先,我们需要查看`main.c...
对于那些渴望成为“阿里人”的求职者而言,笔试环节无疑是一道难以逾越的高墙。为了一窥阿里巴巴笔试题的奥秘,我们将深入解析可能涉及的知识点以及如何准备应对此类挑战。 首先,回顾2009年9月在南京进行的阿里...
3. **算法题解答**:技术面试环节通常会有一道算法题,需在规定时间内完成。 - 建议策略:先快速理解题目要求,再构思解题思路,最后编码实现。 4. **沟通技巧**: - 在面试过程中保持自信,即使遇到不懂的问题也...
3. **实战演练**:面试中可能会给出一道算法题供现场解答,通常时间为20分钟左右。 - **建议**:提前熟悉常见的数据结构与算法,提高解决问题的能力。 #### 六、综合建议 1. **技术积累**:不断学习新知识,提高...
一个合法的表达式由()包围,()可以嵌套和连接,如(())()也是合法表达式;现在有6对(),它们可以组成的合法表达式的个数为多少?
4. 面试题解析:涵盖LeetCode上的经典题目,分析解题思路和最优解法; 5. 实战经验:分享阿里巴巴内部项目中的算法应用,以及面试过程中可能遇到的问题。 三、代码示例 配套的代码示例通常会以Python、Java、C++等...
- 第19题:这是一道关于组合计数的问题,询问的是在一定条件下不同颜色球的组合数。 4. **系统负载与性能监控**: - 第22题:题目涉及系统负载的概念,指出了一分钟、五分钟和十五分钟的平均负载,负载越低说明...
1. **逻辑推理**:这些题目属于逻辑推理题,常见于面试和笔试中,用于测试应聘者的逻辑思维能力。例如Question 1、2、4、5、7、8、9都是关于逻辑推理的题目。Question 1中,肯尼迪的讲话基于美国石油公司应该听从...