在数组中查找单个整数

时间:2015-05-19 17:34:39

标签: java arrays algorithm

我试图解决算法问题。我需要在数组中找到一个整数

e.g {1,1,5,5,5,3,2,2}

输出应为3,因为那是唯一的单个整数。

到目前为止,我创建了一个算法,首先对数组进行排序,然后检查i-1和i + 1元素是否相等,如果不是,则意味着我得到了单个数据。

问题是;对于短输入它工作正常但是对于长输入我收到超时(计算时间太长,所以我的答案没有得到验证)。

你能否给我一些改进算法的提示

static int lonelyinteger(int[] a) {

    Arrays.sort(a);

    if (a.length == 1)
        return a[0];

    for (int i = 0; i < a.length; ++i) {

        if (i == 0) {
            if (a[i + 1] != a[i])
                return a[i];
        } else if (i == a.length - 1) {
            if (a[i] != a[i - 1])
                return a[i];
        } else {
            if (a[i - 1] != a[i] && a[i + 1] != a[i])
                return a[i];
        }  
    }
    return -1;
}

4 个答案:

答案 0 :(得分:1)

你确定你的问题是对的吗?孤独的整数算法问题背后的想法,通常发布在算法解决挑战上,是所有数字成对出现,除了一个。从您使用的样本来看,情况并非如此。

如果所有数字都成对显示,除了一个,找到解决方案的最快方法是对所有元素应用XOR。由于在两个相同元素之间应用XOR会取消它们,因此您将获得您正在寻找的孤立整数。该解决方案的时间复杂度为O(n)。

否则,如果在给定数组中找到的数字超过两次,或者您使用的是您提供的解决方案,则时间复杂度为O(n * logn)。

答案 1 :(得分:1)

对于这个问题,O(N ^ 2)被认为不够“足够快”吗?

这里我列出了10,000,000个具有随机对值的元素。在一个随机点,我把“孤独的整数”5,O(N ^ 2)快速解决它而不需要排序。算法停在它找到的第一个“孤独整数”上。

public static void main(String[] args) {
    Random r = new Random();

    List<Integer> ints = new ArrayList<>();
    for (int i = 0; i < 10000000; i += 2) {
        int randomNumber = r.nextInt(100) + 10;
        ints.add(randomNumber);
        ints.add(randomNumber);
    }
    ints.add(5); // Lonely Integer

    int tempIndex = r.nextInt(ints.size());
    int tempValue = ints.get(tempIndex);
    // Swap duplicate integer with lonely integer
    ints.set(tempIndex, ints.get(ints.size() - 1)); 
    ints.set(ints.size() - 1, tempValue);

    for (int i = 0; i < ints.size(); i++) {
        boolean singleInteger = true;
        for (int j = 0; j < ints.size(); j++) {
            if (j == i) {
                continue;
            }
            if (ints.get(j) == ints.get(i)) {
                singleInteger = false;
                break;
            }
        }

        if (singleInteger) {
            System.out.println("Single instance: " + ints.get(i));
            break;
        }
    }
}

结果:

  

单个实例:5(约10 - 20秒);

更新

你的方法大约3秒钟。

地图解决方案......

public static void main(String[] args) {
    Random r = new Random();

    List<Integer> ints = new ArrayList<>();
    for (int i = 0; i < 10000000; i += 2) {
        int randomNumber = r.nextInt(100) + 10;
        ints.add(randomNumber);
        ints.add(randomNumber);
    }
    ints.add(5); // Lonely Integer
    int tempIndex = r.nextInt(ints.size());
    int tempValue = ints.get(tempIndex);
    // Swap duplicate integer with lonely integer
    ints.set(tempIndex, ints.get(ints.size() - 1));
    ints.set(ints.size() - 1, tempValue);

    Map<Integer, Integer> counts = new HashMap<>();
    for (int i : ints) {
        if (counts.containsKey(i)) {
            counts.put(i, counts.get(i) + 1);
        } else {
            counts.put(i, 1);
        }
    }

    for (Integer key : counts.keySet()) {
        if (counts.get(key) == 1) {
            System.out.println("Single Instance: " + key);
        }
    }
}

结果:

  

单一实例:5(约1 - 3秒)

答案 2 :(得分:1)

首先检查是否Arrays.sort(a);对于非常大的输入而言花费的时间太长。

如果不是这样,您可以按照以下方法改进方法

 static int lonelyinteger(int[] a) {
    if (a[0] != a[1]) return a[0];

    int i = 1;
    while ((i < a.length - 1) && (a[i] == a[i-1] || a[i] == a[i+1])) {
        i++;
    }

    if ((i < a.length -1) || (a[i] != a[i-1]))  return a[i];
    return -1;
}

答案 3 :(得分:0)

排序。然后...

while (true) {
    if (a[0] != a[1]) {
        return a[i].
  } else {
      remove all a[0]s from a.
  }
}

这是O(nlogn)。

找到所有唯一整数的O(n)解决方案(一个没有排序)是有一个哈希并沿着数组运行。如果该数字未出现在哈希中,请为其添加数字。如果确实出现在哈希中,请从哈希中删除该数字。最后,您将在一个哈希中拥有所有唯一的整数。热潮。