题目一:找出数组中重复的数字
在一个长度为n的数组里的所有数组都在0~n-1的范围内。数组中某些数字是重复的,但不知道有几个数字重复了,也不知道每个数字重复了几次。请好处数组中任意一个重复的数字。例如,如果输入长度为7的数组{2,3,1,0,2,5,3},那么对应的输出是重复的数字2或者3。
package offer;
import java.util.Scanner;
public class Test4 {
public static void duplication(int[] num) {
int tmp;
if(num==null||num.length<0)
throw new IllegalArgumentException("未输入数组!");
for(int i=0;i<num.length;i++) {
if(num[i]<0||num[i]>=num.length) {
throw new IllegalArgumentException("输入数组数字在范围外!");
}
}
System.out.println("重复的数字是:");
for (int index = 0; index < num.length; index++) {
while (num[index] != index) {
if (num[index] == num[num[index]]) {
System.out.println(num[index] + " ");
break;
} else {
tmp = num[num[index]];
num[num[index]] = num[index];
num[index] = tmp;
}
}
}
}
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
int[] num = new int[7];
System.out.println("请输入一组数据:");
for (int i = 0; i < 7; i++) {
num[i] = scan.nextInt();
}
duplication(num);
}
}
题目二:不修改数组找出重复的数字
在一个长度为n+1的数字里的所有数字都在1~n的范围内,所以数组中至少有一个数字是重复的。请找出数组中任意一个重复的数字,但不能修改输入的数组。例如,输入长度为8的数组{2,3,5,4,3,2,6,7},那么对应的输出是重复的数字2或者3。
思路:①中间数字4把1~7分为两段:1~4,、5~7;②1~4在数组中出现5次,5~7出现3次,1~4定有重复;③1~4分为1~2和3~4,1~2出现了2次,3~4出现了3次,3~4定有重复;④3出现了两次,4出现了一次。得出3重复。
package offer;
import java.util.Scanner;
public class Test4 {
public static int getCount(int[] arr, int start, int end) {
if (arr == null || arr.length < 0)
throw new IllegalArgumentException("输入数组长度小于0");
for (int i = 0; i < arr.length; i++) {
if (arr[i] <= 0 || arr[i] >= arr.length)
throw new IllegalArgumentException("输入数组的值在范围外");
}
int count = 0;
for (int i = 0; i < arr.length; i++) {
if (arr[i] >= start && arr[i] <= end)
count++;
}
return count;
}
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
System.out.println("请输入一个数组:");
int[] arr = new int[8];
for (int i = 0; i < arr.length; i++) {
arr[i] = scan.nextInt();
}
int end = arr.length - 1;
int start = 1;
System.out.println("重复的数字为:");
while (end >= start) {
int middle = ((end - start) >> 1) + start;
int count = getCount(arr, start, middle);
if (start == end) {
if (count > 1) {
System.out.println(start);
break;
} else {
break;
}
}
if (count > (middle - start + 1)) {
end = middle;
} else {
start = middle + 1;
}
}
}
}
牛客网:在一个长度为n的数组里的所有数字都在0到n-1的范围内。 数组中某些数字是重复的,但不知道有几个数字是重复的。也不知道每个数字重复几次。请找出数组中任意一个重复的数字。 例如,如果输入长度为7的数组{2,3,1,0,2,5,3},那么对应的输出是第一个重复的数字2。
思路:两层循环,第一层循环遍历整个数组,第二层循环寻找数组中与第一层循环停留的下标对应元素相等的数字,找到第一个就停下来。
package offer;
public class Solution3 {
public boolean duplicate(int numbers[],int length,int [] duplication) {
if(numbers==null||numbers.length<=0)
return false;
for(int i=0;i<numbers.length;i++) {
for(int j=i+1;j<numbers.length;j++) {
if(numbers[i]==numbers[j]) {
duplication[0]=numbers[i];
return true;
}
}
}
return false;
}
}
public class Solution {
// 解法2:创建一个布尔型数组,存储numbers数组0~n-1下标对应的值
// 并将这些值作为boolean数组的下标,遍历过将其置为true
// 当遇到下一个true时,就是重复的数字
public boolean duplicate(int numbers[],int length,int [] duplication) {
boolean[] k=new boolean[length];
for(int i=0;i<length;i++){
if(k[numbers[i]]==true){
duplication[0]=numbers[i];
return true;
}
k[numbers[i]]=true;
}
return false;
}
}