题目描述
该系列文章题目和思路均参考自:《剑指Offer》
解法
思路1:对数组进行排序,例如使用快速排序(O(nlgn)),然后对数组进行遍历,判断当前元素与之后的元素是否相等,如果相等即为重复的元素。这种方式简单容易首先想到,但时间复杂度较高。
思路2:使用HashMap,遍历数组然后对每个元素判断Map中是否已经包含该元素。如果已经包含,即为重复元素。这种方式的时间复杂度为O(n),但空间复杂度较高。
思路3:以上两种方法都没有用到这个数组中的数字在0-n-1范围这一特性,根据这个特性考虑如下思路。因为数组中的元素范围都在0-n-1,因此
- 首先对数组中的每个元素(m)进行判断,如果m=它的下标i,则继续扫描下一个元素。
- 如果不是则拿m和第m个数字进行比较,如果相等,则说明找到了重复的数字。
- 如果比较结果不等,就把第i个数字和第m个数字进行交换,直到发现一个重复的数字。
代码实现
/**
* P39_问题3
*/
public class O_SearchRepeatNumber {
public static void searchRepeatNumber(int[] array) {
if (array.length == 0)
return;
for (int i = 0; i < array.length; i++) {
while (array[i] != i) {
if (array[i] == array[array[i]]) {
System.out.println(array[i]);
return;
}
// swap array[i] with array[array[i]]
int temp = array[i];
array[i] = array[temp];
array[temp] = temp;
}
}
}
public static void main(String[] args) {
int[] array = {2,3,1,0,2,5,3};
searchRepeatNumber(array);
}
}
题目2
该题目和问题1中的描述很相似,但要求不能修改输入的数组。
思路1:依然使用一个HashMap作为辅助存储空间的思路依然可行。这里实现这个思路。
public class O_SearchRepeatNumber {
public static void searchRepeatNumber_2(int[] array) {
if (array.length == 0)
return;
int[] count = new int[array.length+1];
for (int i = 0; i < count.length; i++) {
count[i] = 0;
}
for (int i = 0; i < array.length; i++) {
int temp = array[i];
if (count[temp] == 0)
count[temp] = 1;
else
System.out.println(temp);
}
}
public static void main(String[] args) {
int[] array2 = {1,3,1,0,2,5,3};
searchRepeatNumber_2(array2);
}
}