自从我讨论任何编码或算法面试问题以来已经有很长时间了,因此我想重新考虑一种最流行的基于数组的编码问题,即在给定数组中查找缺失的数字。 在进行编程工作面试之前,您可能已经听说过或看到过此问题,但是面试官通常会使用许多不同的版本来提高难度,以使候选人感到困惑并进一步测试其适应频繁变化的能力。 过去,我已经演示了如何使用BitSet在Java中的未排序整数数组上以及在排序数组中查找缺失的数字 ,但是,只有一个缺失的数字并且没有任何重复。
数组包含重复项并且缺少多个数字,您该怎么办?
1.问题陈述:
您给定了一个大小为N的整数数组。该数组包含从1到N-1的数字,但是在包含重复项的数组中缺少几个数字。 编写一个Java程序以打印序列中缺少的数字。
例如,如果给定数组为
{1,1,2,3,5,5,7,9,9,9}那么它的长度
10,其中包含1到9之间的数字。在这种情况下,缺少的数字是4、6和8。
2.解决方案:
找到阵列失踪人数 ,你可能会认为我们前面的解决方案计算所有数字的总和 ,并从预期的总和扣除它来寻找失踪的数字,但不幸的是不会在这种情况下工作,因为更多缺少一个数字
在这种情况下,我们需要使用其他方法,例如您在学校中看到的点名通话。
老师有一个列出所有学生姓名的登记册,他在列表中浏览并用红色标记缺席。 我们可以使用相同的方法来查找列表中所有缺少的数字。
我们可以将数组用作寄存器,并将索引用作数字名称。 我们遍历给定的数组,并通过存储它们各自的索引之一来标记所有存在的数字。 例如,如果给定数组中的第一个数字为5(由于未对数组进行排序),则我们将1存储在索引5中,例如register[5] = 1
这些人缺席或缺席。
该解决方案对于重复项也是安全的,因为如果一个数字出现一次或两次,我们只需将1存储在相应的索引中即可。
3.代码:
未排序整数数组中的数字遗漏的问题,是时候将该解决方案变成代码并运行Java程序了。
/*
* Java Program to find missing numbers in an integer
* array with duplicates. Array may contains more
* than one duplicates.
*
* input: {1, 1, 2, 3, 5, 5, 7, 9, 9, 9};
* output: 4, 6, 8
*/
public class Hello {
public static void main(String[] args) {
// given input
int[] input = { 1, 1, 2, 3, 5, 5, 7, 9, 9, 9 };
// let's create another array with same length
// by default all index will contain zero
// default value for int variable
int[] register = new int[input.length];
// now let's iterate over given array to
// mark all present numbers in our register
// array
for (int i : input) {
register[i] = 1;
}
// now, let's print all the absentees
System.out.println("missing numbers in given array");
for (int i = 1; i < register.length; i++) {
if (register[i] == 0) {
System.out.println(i);
}
}
}
}
Output
missing numbers in given array
4
6
8
我们已经对输入数组进行了硬编码,但是您也可以修改程序以通过使用Scanner类从用户获取输入,如本示例所示。
该代码与解决方案完全相同,我们通过复制原始数组的长度来创建另一个数组,并使用它标记存在的数字。
不在1到N-1之间,那么我们就不能使用数组。
中算法和代码的摘要,以使您更好地理解:
4.分析
空间复杂度为O(n)
这意味着如果数组太大,即包含整数范围内的所有数字,那么我们将有更多的内存可能不可用,并且我们的程序可能会在Java中抛出OutOfMemoryError 。 这甚至更有可能,因为数组需要连续的内存块。
因此,如果我们可以删除实际上不容纳任何内容的附加数组,并找到一种方法来存储丢失的数字,而该数字远远小于我们可以改进此解决方案的所有数字,那么您可以考虑一下。
时间复杂度 ,您可以看到我们遍历整个数组以标记所有存在的数字,然后再次遍历具有相同长度的另一个数组以查找缺席者。 这意味着该解决方案的时间复杂度为O(n)+ O(n)或O(2N),但仍以Big O表示法表示O(n)
找到在给定数组中进行迭代时打印缺席者的方法,则可以进一步改进此解决方案。 再说一遍,你们要想一想。
在给定整数array中查找缺失数字的经典问题