对于这个问题,有一个简单的贪心算法。
首先,有 n 个按升序排列的元素,为了使它们不同,每个元素应该比其前面的元素至少大1。
因此,我们有
1,2,3...n
现在,所有 n
个数字的总和为 n*(n + 1)/2
剩下的是 left = N - n*(n + 1)/2
为了让最后一个元素尽可能小,我们需要将 left
的差异散布到所有数字上
因此,我们有
1 + left/n, 2 + left/n,..., n + left/n
如果 left % n != 0
,我们只需要将额外的1添加到最后的 left % n
个元素中。
注意: 如果 N < n*(n + 1)/2
,则没有解决方案。
例子:
所以,对于 n = 4 和 N = 12
First, we start with
1, 2, 3, 4
left = 12 - (4*5/2) = 2
So, now we have
1 + (2/4), 2 + (2/4), 3 + (2/4), 4 + (2/4) = 1, 2, 3, 4
As left % n = 2
Finally, we have
1, 2, 3 + 1, 4 + 1 = 1, 2, 4, 5
同样地,对于 n = 3,N = 10。
First, we start with
1, 2, 3
left = 10 - (3*4/2) = 4
So, now we have
1 + (4/3), 2 + (4/3), 3 + (4/3) = 2, 3, 4
As left % n = 1
Finally, we have
2, 3, 4 + 1 = 2, 3, 5
伪代码,时间复杂度O(n)
int[]result = new int[n];
int left = N - n*(n + 1)/2;
for(int i = 0; i < n; i++){
result[i] = i + 1 + left/n;
if(i >= n - (left % n)){
result[i]++;
}
}
return result;
2, 3, 5
。 - Pham Trung