我通过以下功能得到错误答案。
vector<int> repeatedNumber(const vector<int> &A) {
int n = A.size();
long long linear_sum = 0,square_sum = 0;
int i = 0;
for(;i<n;i++){
linear_sum += A[i]; //LINE 1
square_sum += A[i]*A[i]; //LINE 2
}
linear_sum = linear_sum - (n*(n+1))/2;
square_sum = square_sum - (n*(n+1)*(2*n+1))/6;
square_sum /= linear_sum;
vector<int> ans;
ans.push_back((linear_sum+square_sum)/2);
ans.push_back((-linear_sum+square_sum)/2);
return ans;
}
但是当我用:
替换LINE 1和LINE 2时linear_sum += (long long)A[i];
square_sum += (long long)A[i]*(long long)A[i];
我得到了正确的答案。为什么只需将int类型转换为long来解决问题。
答案 0 :(得分:3)
当您将两个int
值相乘时,结果将计算为int
。
如果乘以的值对于int
而言太大,则会得到&#34;未定义的行为&#34; (在大多数常见硬件中,你只是得到一个看似随机的结果)。
例如33554432
(即1<<25
== 2 25 )对于32位整数是可以的,但是它的平方1125899906842624
(即2 < sup> 50 )不是。
在计算乘法之前,将long long
项转换为int
,有希望扩展计算正确完成的范围。
这些问题在本机提供Python或Lisp等任意精度整数的语言中不存在。
请注意,long long
和long long
的大小确实相同(您只能确定int
不是较小而不是eventListener
)。
答案 1 :(得分:2)
关键在于:
A[i]*A[i]
这可能太大,溢出int
,之后只会转换为long long
,但是。
(long long)A[i]*(long long)A[i];
首先被转换然后相乘并且不会溢出long long