数组求和的溢出问题
简单水篇文章。
一个面试题,int64 数组求和,题目不保证中间过程不会溢出,只能保证结果不溢出。
这题有一个小技巧,直接转换成 uint64 相加,结果再转换回 int64 就行了。这就是补码的性质。
int64_t sum(std::vector<int64_t> arr) {
uint64_t res = 0;
for (int64_t i : arr) {
res += i;
}
return res;
}
但是如果不让用 uint64(虽然这个限制没有道理),也是有办法的。
我们可以用双指针,指针 i 只找正数,指针 j 只找负数。求和过程中,sum 是正数就和 j 指向的负数相加,否则和 i 指向的正数相加。
int64_t sum(std::vector<int64_t> arr) {
size_t i = 0;
size_t j = 0;
int64_t res = 0;
while (true) {
while (i < arr.size() && arr[i] <= 0) {
i++;
}
while (j < arr.size() && arr[j] >= 0) {
j++;
}
if (i == arr.size() && j == arr.size()) {
break;
}
if (res > 0 || i == arr.size()) {
res += arr[j];
j++;
} else {
res += arr[i];
i++;
}
}
return res;
}