我试图解决算法问题。我需要在数组中找到一个整数
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;
}
答案 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)解决方案(一个没有排序)是有一个哈希并沿着数组运行。如果该数字未出现在哈希中,请为其添加数字。如果确实出现在哈希中,请从哈希中删除该数字。最后,您将在一个哈希中拥有所有唯一的整数。热潮。