题目
假设你有一个用1001个整数组成的数组,这些整数是任意排列的,但是你知道所有的整数都在1到1000(包括1000)之间。此外,除一个数字出现两次外,其他所有数字只出现一次。假设你只能对这个数组做一次处理,用一种算法找出重复的那个数字。如果你在运算中使用了辅助的存储方式,那么你能找到不用这种方式的算法吗?
解法
1. 如果使用辅助存储的方式,这里可以选择Hash表,或者是HashMap进行统计每个词出现的次数。然后对统计结果进行查找,出现次数为2的即为重复的数字。时间复杂度:O(n)。
2. 如果不使用辅助存储,那么一个简单的方式就是:sum(1001个数) - sum(1 to 1000),得到的值即为重复的数字。时间复杂度:O(n)。
3. 另一个不借助辅助存储的方式为:找出数组中重复数字的问题,可以借助XOR的位运算。XOR的特点是,两个相同的数运算结果为0(A XOR A = 0),不同的数运算结果为1 (A XOR B = 1,A != B)。因此这里可以将这1001个数依次与1到1000进行XOR运算,这样会消掉其中的1000个数,最后剩下的数就是重复的数字。
HashMap的方式:
FIND-REPEAD-NUM(int[] array):
Map<Integer, Integer> countMap = new HashMap<Integer, Integer>();
for i to array.length:
if countMap.contain(array[i]) == false:
countMap.put(array[i], 1);
else
int count = countMap.get(array[i]);
countMap.put(array[i], count++);
foreach key in countMap:
if countMap.get(key) == 2:
return key;
return null;
计算SUM差的方式:
代码省略。
XOR运算的方式:
FIND-REPEAD-NUM(int[] array):
int result = array[0]
for i = 1 to 1000: // 这里的1000包含再循环中
result ^= array[i] ^ i;
return result;