[LeetCode—003][Java]分糖果

题目:
我们买了一些糖果 candies,打算把它们分给排好队的 n = num_people 个小朋友。
给第一个小朋友 1 颗糖果,第二个小朋友 2 颗,依此类推,直到给最后一个小朋友 n 颗糖果。
然后,我们再回到队伍的起点,给第一个小朋友 n + 1 颗糖果,第二个小朋友 n + 2 颗,依此类推,直到给最后一个小朋友 2 * n 颗糖果。
重复上述过程(每次都比上一次多给出一颗糖果,当到达队伍终点后再次从队伍起点开始),直到我们分完所有的糖果。注意,就算我们手中的剩下糖果数不够(不比前一次发出的糖果多),这些糖果也会全部发给当前的小朋友。
返回一个长度为 num_people、元素之和为 candies 的数组,以表示糖果的最终分发情况(即 ans[i] 表示第 i 个小朋友分到的糖果数)。

方法一:
for循环分糖果

public int[] distributeCandies(int candies, int num_people) {
		//返回的数组
		int[] result = new int[num_people];
		//控制循环
		int i = 0;
		//控制下一次应该分多少颗糖果
		int count = 1;
		//循环体,条件是是否还有剩余糖果
		while (candies != 0) {
			//如果派到最后一位小朋友,下一位就轮到第一位小朋友
			if (i == num_people) {
				i = 0;
			}
			//判断糖果的数量是否充足
			if (candies >= count) {
				//给小朋友发糖果
				result[i] += count;
				//从糖果里减去发出去的
				candies -= count;
			} else {
				//如果糖果数量不足,就把剩下的糖果全部分给这位小朋友,并退出循环返回结果
				result[i] += candies;
				return result;
			}
			i++;
			count++;
		}
		return result;
	}

结果:
测试结果
方法二:
结合数学的等差求和公式,可以先求出糖果在第几次发的时候不够。
在这里插入图片描述
在这里插入图片描述
变成了一个一元二次方程,它的求根公式:
在这里插入图片描述
求出的 x 的值,向下取整,计算Sncandies 比较,如果恰好相等,则刚好分完,不然就把剩下的糖果派给第n+1位小朋友。

先封装好等差数列的求和公式:

	//等差数列求和
	public int colSn(int a1,int n,int d) {
		int Sn = (int) (n*a1 + 0.5*(n*(n-1)*d));
		return Sn;
	}

方法:

public int[] distributeCandies2(int candies, int num_people) {
		//返回的数组
		int[] result = new int[num_people];
		//求二次方程求解
		int x = (int) Math.floor(-0.5 +Math.sqrt((0.25 + 2 * candies))); 
		//派出糖果的数量
        int Sn = colSn(1,x,1);
        //派了多少轮
        int n = x/num_people;
        //最后一轮派到了哪一位
        int m = x%num_people;
        	//计算每一位小朋友一共拿到多少糖果
        	for (int i = 0;i<num_people;i++) {
        		//第m位小朋友 和 m之前的小朋友 比 m之后的小朋友多拿一次
        		if(i<m) {
        			//多拿一次糖果的小朋友
        			result[i] = colSn(i+1,n+1,num_people);
        		}else if(i==m){
        			//最后一位分到糖果的小朋友拿走剩下的(不管是不是符合数据的数量,都会全部拿走)
        			result[i] = colSn(i+1,n,num_people)+candies-Sn;
        		}else {
        			//后面的小朋友就少拿一次
        			result[i] = colSn(i+1,n,num_people);
        		}
			}
        	return result;
    }

结果:
测试结果
PS:计算机,计算机,本来就是为了计数而生的,我们在使用的时候应该多点联系上数学,用数学优化我们的算法。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值