寻找和为C的N个数组合:高低差值不超过1的算法实现
问题:构造满足条件的整数数组
给定两个整数C(总和)和N(元素个数),需要生成一个包含N个整数的数组,满足以下要求:
- 数组所有元素的总和等于C
- 数组中最大值与最小值的差值不超过1
示例
- 当C=26、N=7时,结果为
[4, 4, 4, 4, 4, 3, 3] - 当C=11、N=5时,结果为
[3, 2, 2, 2, 2] - 当C=17、N=4时,结果为
[5, 4, 4, 4] - 当C=10、N=3时,结果为
[4, 3, 3] - 当C=5、N=2时,结果为
[3, 2]
问题分析
这个问题的核心是数学上的除法拆分逻辑:
把C除以N,得到整数商k = C / N,余数r = C % N。
- 余数r代表有r个元素需要取
k + 1,这部分额外的1刚好凑够余数r,总和会等于r*(k+1) + (N-r)*k = N*k + r = C - 剩下的
N - r个元素直接取k即可
这样构造出的数组自然满足总和要求,且最大值与最小值的差值要么是1(r≠0时),要么是0(r=0时,所有元素相等),完全符合题目限制。
完善后的代码
基于你给出的代码片段,完整的Java实现如下:
// 假设N和C已经被正确声明并赋值为正整数 int[] numbers = new int[N]; int k = C / N; // 基础值(数组的最小值) int r = C % N; // 需要取k+1的元素个数 // 先填充r个k+1的元素 for (int i = 0; i < r; i++) { numbers[i] = k + 1; } // 再填充剩下的N-r个k的元素 for (int i = r; i < N; i++) { numbers[i] = k; }
代码说明
- 计算
k:这是数组中大部分元素的取值,对应C除以N的整数商 - 计算
r:这是需要比k大1的元素数量,对应除法的余数 - 分两次填充数组:前r个位置放
k+1,剩下的位置放k- 如果需要结果不按大小顺序排列,你可以额外添加打乱数组的逻辑(比如用
Collections.shuffle将数组转成List打乱后再转回数组),但目前的写法完全匹配示例中的输出格式。
- 如果需要结果不按大小顺序排列,你可以额外添加打乱数组的逻辑(比如用
比如用C=26、N=7验证:
- k=26/7=3,r=26%7=5
- 前5个元素是4(3+1),后2个是3,总和为
5*4 + 2*3 = 26,完全符合要求。
内容的提问来源于stack exchange,提问作者Alexander Hristov
相关产品推荐
相关产品推荐

