剑指Offer- 面试题3:数组中重复的数字
题目一:找出数组中重复的数字。
在一个从度为n的数组里的所有数字都在0~n-1的范围内,数组中某些数字是重复的,但不知道有几个数字重复的数字。例如,如果输入长度为7的数组{2,3,1,0,2,5,3},那么对应的输出是重复的数字2或者3.
用Java实现:
import java.util.ArrayList;
import java.util.List;
public class DuplicationInArray {
static List<Integer> duplication=new ArrayList<>() ;
private static boolean duplicate(int[] numbers, int length, List<Integer> duplication) {
if(numbers==null||length<=0){
return false;
}
for(int i=0;i<length;i++){
if(numbers[i]<0||numbers[i]>length-1){
return false;
}
}
int m=0;
boolean repeat=false;
for(int i=0;i<length;i++){
while (numbers[i]!=i){
if(numbers[i]==numbers[numbers[i]]){
duplication.add(numbers[i]);
break;
}
int temp=numbers[i];
numbers[i]=numbers[temp];
numbers[temp]=temp;
}
}
if(duplication.isEmpty()) {
return false;
}else{
return true;
}
}
public static void main(String[] args) {
int[] numbers = {2, 3, 1, 0, 2, 5, 3};
if(duplicate(numbers,7,duplication)){
System.out.println(duplication.toString());
}else{
System.out.println("没有重复值!");
}
}
}
运行结果:
[2, 3]
题目二:不修改数组找出重复的数字
在一个长度为n+1的数组里的所有数字都在1~n的范围内,所以数组中至少有一个数字是重复的。请找出数组中任意一个重复的数字,但蹦年修改输入的数组。例如,如果输入长度为8的数组{2,3,5,4,3,2,6,7},那么对应的输出是重复的数字2或者3;
public class DuplicationInArrayNoEdit {
private static int getDuplication(final int[] numbers, int length) {
if (numbers == null || length <= 0) {
return 0;
}
int start = 1;
int end = length - 1;
while (end >= start) {
int middle = ((end - start) >> 1) + start;
int count = countRange(numbers, length, start, middle);
if (end == start) {
if (count > 1) {
return start;
} else {
break;
}
}
if (count > (middle - start + 1)) {
end = middle;
} else {
start = middle + 1;
}
}
return -1;
}
private static int countRange(final int[] numbers, int length, int start, int end) {
if (numbers == null) {
return 0;
}
int count = 0;
for (int i = 0; i < length; i++) {
if (numbers[i] >= start && numbers[i] <= end) {
++count;
}
}
return count;
}
public static void main(String[] args) {
int[] numbers = {2, 3, 5, 4, 3, 2, 6, 7};
int number = getDuplication(numbers, 8);
switch (number) {
case 0:
System.out.println("数组为空");
break;
case -1:
System.out.println("没有重复");
break;
default:
System.out.println(number);
break;
}
}
}
运行结果:
3
- 这种算法不能保证找出所有重复的数字。下面是我用桶算法来找出所有重复的数字。
public class DuplicationInArrayNoEdit2 {
public static void main(String[] args){
int[] numbers={2,3,5,4,3,2,6,7};
int[] array=new int[8];
for(int i=0;i<8;i++){
array[numbers[i]]++;
}
for(int i=1;i<8;i++){
if(array[i]>1){
System.out.print(i+" ");
}
}
System.out.println();
}
}
运行结果:
2 3