数组有N-2个数字,数字的范围为1 ... N,没有反复的元素,要求打印缺少的2个数字,不能够用额外
的空间。
思路一:整个数组进行排序。数组中缺了两个数字,直观上能够通过把数字排序,然后从头到尾进行扫描。找到缺失的两个数字。由于有排序,而排序的时间复杂度最快为O(NLogN)。
思路二:假如我们把数组中全部的数字加起来得到一个总数M0, 而1+2+3+4...+N = N(N+1)/2, 用后一个数字减去前一个数字的结果应该刚好是缺失的两个数字的加和。假定缺失的两个数字分别为x和y,则x+y= N(N+1)/2 - M0.
现在一个方程有两个未知数,是无法求出确定解的,我们需要构建另外一个方程:
不失一般性: 假设x < y, x和y的均值mid = x+(y-x)/2,则有x<=mid,y>mid, 除法可能是mid变小,所以x可能等于mid,但是y一定大于mid。
做一个特殊的计算,
int i;
int calc1=0;
int calc2=0;
int sum0=0;
int sum1 = n*(n+1)/2;
int mid = (sum1-sum0)/2;
for(i=0;i<n-2;i++)
sum0+=num[i];
for(i=0;i<n-2;i++){
if(num[i]<=mid)
calc1 = calc1-num[i];
else
calc1 = calc1+num[i];
}
//calc2 相比与calc1 多减了一个x,多加了一个y
for(i=1;i<=n;i++){
if(i<mid)
calc2 = calc2-i;
else
calc2 = calc2+i;
}
//calc2 相比与calc1 多减了一个x,多加了一个y,这样用calc2 - calc1 = y - x;