题目:给定一个长度为n+1的int数组,其内元素为1到n,数组中除一个元素外其他元素都只出现一次,求重复出现的元素。要求时间小于O(n^2),空间为O(1)。
1、要求时间复杂度小于O(n^2),那么肯定存在一种算法时间复杂度为O(nlgn),想到二分查找。
public static int findDuplicate(int[] nums) {
if (nums.length == 0 || nums == null)return 0;
int low = 1, high = nums.length - 1, mid;
while (low < high) {
mid = low + (high - low) / 2;
int count = 0;
for (int i = 0; i < nums.length; i++) {
if (nums[i] <= mid)
count++;
}
if (count > mid)
high = mid;
else
low = mid + 1;
}
return low;
}
2、通过位操作得到重复的位,把重复的位相加得到结果。
public int findDuplicate(int[] nums) {
int n = nums.length-1, res = 0;
for (int p = 0; p < 32; ++ p) {
int bit = (1 << p), a = 0, b = 0;
for (int i = 0; i <= n; ++ i) {
if ((i & bit) > 0) ++a;
if ((nums[i] & bit) > 0) ++b;
}
//b>a说明有重复的位
if (b > a) res += bit;
}
return res;
}