指出潜在的溢出错误
Point out potential overflow bugs
这是我解决面试问题的方法。链接
给定一个包含n个从1到n的整数的只读数组。每个整数只出现一次,除了A出现两次,B没有出现。返回A和B。注意:你的算法应该有一个线性的运行复杂度。你能在不使用额外内存的情况下实现它吗?请注意,在输出中,A应该在b之前。N <= 10^5
看起来好像某个地方有溢出问题。你能指出这些地方并提出解决办法吗?
typedef long long int unit;
vector<int> Solution::repeatedNumber(const vector<int> &A) {
unit n = A.size();
unit sum = n*(n+1)/2;
unit sumsq = n*(n+1)*(2*n+1)/6;
unit arrsum = std::accumulate(A.begin(), A.end(), 0);
unit arrsq = 0;
for(int item : A) {
arrsq += (unit)item*item;
}
unit c1 = arrsum - sum;
unit c2 = arrsq - sumsq;
unit a = (c2/c1 + c1);
a/=2;
unit b = (c2/c1 - c1);
b/=2;
return {a, b};
}
p。这可能是溢出问题,因为同样的解决方案在Python中也有效。
这是一个问题的作者提供的解决方案。有趣的是他是如何通过减法来解决求和中的溢出问题的。
class Solution {
public:
vector<int> repeatedNumber(const vector<int> &V) {
long long sum = 0;
long long squareSum = 0;
long long temp;
for (int i = 0; i < V.size(); i++) {
temp = V[i];
sum += temp;
sum -= (i + 1);
squareSum += (temp * temp);
squareSum -= ((long long)(i + 1) * (long long)(i + 1));
}
// sum = A - B
// squareSum = A^2 - B^2 = (A - B)(A + B)
// squareSum / sum = A + B
squareSum /= sum;
// Now we have A + B and A - B. Lets figure out A and B now.
int A = (int) ((sum + squareSum) / 2);
int B = squareSum - A;
vector<int> ret;
ret.push_back(A);
ret.push_back(B);
return ret;
}
};
问题是:
unit arrsum = std::accumulate(A.begin(), A.end(), 0);
您需要使用0LL
使其将值累加为long long
。
演示问题的代码:
int main()
{
vector<int> A;
for (int i = 0; i < 1000000; ++i)
A.push_back(1000000);
long long arrsum = accumulate(A.begin(), A.end(), 0LL);
cout << arrsum;
return 0;
}
输出不带LL
的-727379968
和正确的结果。
请注意,您也可以使用accumulate
来计算平方和:
unit arrsq = accumulate(A.begin(), A.end(), 0LL,
[](unit x, unit y) { return x + y*y; });
潜在的溢出问题有:
unit sum = n*(n+1)/2;
这里n的最大值是10^5。因此,n*(n+1)将产生10^10,然后根据运算符优先级计算除法。
第二名是
unit sum = n*(n+1)(2*n+1)/6;
这里计算的中间值最高可达10^15。
在计算所有数字的平方和时也会出现整数溢出
相关文章:
- 为什么我在leetcode上收到AddressSanitizer:地址0x602000000058上的堆缓冲区溢出错误
- 在 leetcode 上提交解决方案时出现堆栈缓冲区溢出错误
- 我的 int main() 中出现堆栈溢出错误
- 使用 strcat 获取缓冲区溢出错误
- 如何修复此特征矩阵反演溢出错误?
- 如何修复递归函数导致的堆栈溢出错误?C++
- 没有 climits 库的溢出错误
- 当我尝试为结构分配新指针时出现堆栈溢出错误
- 应该如何读取堆缓冲区溢出错误消息?
- 初始化数组并出现堆栈溢出错误
- 将 Vector<int> 推送到 Vector<vector 时出现堆溢出错误<int>>
- 为什么 #include <string> 在这里防止堆栈溢出错误?
- 我在 36603 以上输入的任何数组大小时都会返回"堆栈溢出"错误。如何使字符串能够捕获整个.txt文件?
- Boost::序列化存储结构时的堆栈溢出错误
- GetModuleFilenameEx返回0,getlasterror返回溢出错误.我究竟做错了什么
- std::堆栈和堆栈溢出错误的数组分配
- 为什么编写的代码在执行时出现溢出错误
- C 堆栈溢出错误
- 编译器或 CPU 中的 64 位溢出错误
- 创建DLL导出对象时发生堆栈溢出错误