查找已排序数组中唯一的重复元素

时间:2017-01-23 06:47:05

标签: java arrays xor

我知道在排序数组中找到非重复元素的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)空间中重复的一个元素?

3 个答案:

答案 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; 
}