楼主思路是对的,但是写得复杂了,关键就是现有余数r和新的余数a[i] % N合并这步,可以直接判断相加后是否大于N,因为r和a[i] % N的范围都是左闭右开区间[0, N),因此N-r和a[i] % N的范围也是[0, N),比较大小即可。 int get_average(int a[], int n) { int aver = 0; int rest = 0; // [0, n) for (int i = 0; i < n; ++i) { aver += a[i] / n; int temp = a[i] % n; if (temp < 0) { temp += n; aver -= 1; } if (rest > n - temp) { // rest + temp > n,防止溢出 aver++; rest -= (n - temp); } else { rest += temp; } } return (aver >= 0) ? aver : aver + 1; // 假定负数结果向0取整 } 思路参考Quora上的问答,但是原***括楼主的做法都有一点没考虑到,那就是负数是否向0取整的问题。比如-25 / 9和-25 % 9的值,在C/C++/Java这种语言中,结果分别是-2和-7,而在中间处理时,合适的结果应该是-3和2,否则会出问题。比如楼主的程序对{-10, 3, 9}结果是1,对{-10, 3, 8}结果是0,对{-10, 3, 7}的结果是-1。原答案的程序对{-10, 3, 9}结果是1,对{-10, 3, 8}结果是0,对{-10, 3, 7}的结果是0。但如果最后结果需要负数向0取整的话,还要再判断结果是否为负数,若为负数,则需要加1。 另外,对于输入是数据流而非固定数组的情况,稍微就有点麻烦。设x(k)和r(k)依次是数组a[1..k](为方便,下标从1开始)的平均值(取整)和余数。那么有 x(k+1) = (k * x(k) + r(k) + a[k+1]) / (k+1) = x(k) + (r(k) + a[k+1] - x(k)) / (k+1) r(k+1) = (r(k) + a[k+1] - x(k)) % (k+1) 关键就是在不溢出的情况下求(r(k) + a[k+1] - x(k)) / (k+1),相当于求大小为3的数组{r(k), a[k+1], -x(k)}的加权平均值,不过权重不是1/3而是1/(k+1)。看似如此,实际上-x(k)可能溢出,因为INT_MAX的绝对值比INT_MIN的绝对值小1,所以x(k)是INT_MIN即0x80000000的时候,-x(k)仍然是0x80000000,溢出。至于数据流特别大,也就是说元素数量k超过了int的范围的话,考虑就更为复杂了。综上,这个问题其实……仔细想下其实没那么简单……不知道楼上说归并的是个什么思路……
点赞 1

相关推荐

头像
不愿透露姓名的神秘牛友
05-23 10:24
已编辑
趵突泉实验室 研发岗 12➕4
点赞 评论 收藏
转发
比亚迪商研院 f1级 12k第二年会降薪
点赞 评论 收藏
转发
牛客网
牛客企业服务