我知道在排序数组中找到非重复元素的XOR技巧(以前曾被问过):
public int singleNumber(int[] nums) {
int result = 0;
for (int i = 0; i < nums.length; i++) {
result = result ^ nums[i];
}
return result;
}
但是我们如何使用相同的逻辑来做相反的事情?
更具体地说:考虑一个排序数组,其中每个元素只出现一次,我们如何找到在O(1)空间中重复的一个元素?
答案 0 :(得分:1)
如果您想要丢弃甚至重复次数,那么XOR技巧只会很整洁。看待它的一种方法是说数组中所有元素的xor是该数组奇异重复元素的xor ;所以,如果只有一个奇怪的重复元素,你可以用这种方式找到它。并且您根本不需要对数组进行排序:
// could also have called it xorOfOddlyRepeatingIntsInArray(int[] a)
public static int findSingleNonEvenlyRepetingIntInUnsortedArray(int[] a) {
int x = 0;
for (int i: a) x ^= i;
return x;
}
根据您的要求,这两个片段在O(1)空间和O(n)时间内的排序数组中找到重复元素:
public static int findSingleRepeatingIntInSortedArray1(int[] a) {
for (int i=0; i<a.length-1; i++) if (a[i] == a[i+1]) return a[i];
return -1;
}
public static int findSingleRepeatingIntInSortedArray2(int[] a) {
for (int i=0; i<a.length-1; i++) if ((a[i] ^ a[i+1]) == 0) return a[i];
return -1;
}
但您应该更喜欢版本1,因为a[i] == a[i+1]
比(a[i] ^ a[i+1]) == 0
,(a[i] - a[i+1]) == 0
或(a[i] & a[i+1]) == a[i]
或其他神秘变体更具可读性,以检查是否相等。 Xor在这种情况下不会给你买任何东西。
对于笑声和咯咯笑声,此代码在未排序数组中的O(1)空间中找到单个重复值:
public static int findSingleRepeatingIntInSortedArray3(int[] a) {
for (int i=0; i<a.length; i++) {
for (int j=i+1; j<a.length; j++) {
if (a[i] == a[j]) return a[i];
}
}
return 0;
}
是的,它是O(n ^ 2)时间,并且有更快的方法来找到第一个重复元素(想到排序) - 但它是问题的有效答案。
答案 1 :(得分:0)
我认为有人删除了使用XOR的评论。这是:
private int returnNumber(int[] nums) {
int result = 0;
for (int i = 1; i < nums.length; i++) {
if ((nums[i] ^ nums[i - 1]) == 0) {
result = nums[i];
break;
}
}
return result;
}
我真的不确定这是否使用O(1)。
答案 2 :(得分:-1)
我没有设法找到基于XOR的解决方案,但这个令人惊讶的简单解决方案可以实现这一技巧。
public static int getRepeatingValue(int[] nums) {
for (int i = 1; i < nums.length; i++) {
if (nums[i] == nums[i - 1]) {
return nums[i];
}
}
return -1;
}