关注
楼主思路是对的,但是写得复杂了,关键就是现有余数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
相关推荐
点赞 评论 收藏
转发
点赞 评论 收藏
转发
牛客热帖
正在热议
# 和牛牛一起刷题打卡 #
9616次浏览 832人参与
# 机械制造薪资爆料 #
348194次浏览 4099人参与
# 牛客帮帮团来啦!有问必答 #
1057472次浏览 16018人参与
# 通信硬件薪资爆料 #
250556次浏览 2361人参与
# 晒一晒我的offer #
3727083次浏览 57560人参与
# 面试中,你被问过哪些奇葩问题? #
19319次浏览 149人参与
# 你收到了团子的OC了吗 #
525335次浏览 6240人参与
# 毕业租房也有小确幸 #
38393次浏览 3175人参与
# 你怎么评价今年的春招? #
9557次浏览 161人参与
# 我想象的工作vs实际工作 #
104227次浏览 1681人参与
# 提前批和秋招有什么区别 #
28898次浏览 695人参与
# 春招你拿到offer了吗 #
398013次浏览 5747人参与
# 秋招开了,你想投哪些公司呢 #
132454次浏览 3426人参与
# 字节跳动工作体验 #
73432次浏览 2018人参与
# 实习生应该准时下班吗 #
88416次浏览 649人参与
# 来选选带哪个offer回家过年 #
191761次浏览 1838人参与
# 你的秋招进行到哪一步了 #
392911次浏览 6641人参与
# 腾讯工作体验 #
151276次浏览 1478人参与
# 浅聊一下我实习的辛苦费 #
99346次浏览 1000人参与
# 百度工作体验 #
28546次浏览 286人参与