题目一
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
public class Array3 {
/**
* 面试题3:数组中重复的数字
* 题目一:找出数组中重复的数字。在一个长度为n的数组里的所有数字都在0~n-1的范围内。数组中某些数字是重复的。请找出数组中任意一个重复的数字
* 例如:如果输入长度为7的数组{2,3,1,0,2,5,3},那么对应的输出是重复数字2或者3
*/
public static void main(String[] args) {
//测试用例的选择
//正常数组{2,3,1,0,2,5,3}
//不正常数组{2,4,1,0}
//无效数组{},{9,9}
int[] test1 = {2, 3, 1, 0, 2, 5, 3};
int[] test2 = {2, 3, 1, 0};
int[] test3 = {};
int[] test4 = {9, 9};
System.out.println(function4(test1));
System.out.println(function4(test2));
System.out.println(function4(test3));
System.out.println(function4(test4));
}
//暴力解法
private static int function1(int[] array1) {
int length = array1.length;
if (length <= 1) {
return 0;
}
for (int j : array1) {
if (j > length) {
return 0;
}
}
for (int i = 0; i < length; i++) {
for (int j = i + 1; j < length; j++) {
if (array1[i] == array1[j]) {
return array1[i];
}
}
}
return 0;
}
//先排序,后暴力
private static int function2(int[] array2){
if(array2.length<=1||array2[array2.length-1]>array2.length){
return 0;
}
Arrays.sort(array2);
for(int i = 0; i< array2.length - 1;i++){
if (array2[i]==array2[i+1]){
return array2[i];
}
}
return 0;
}
//哈希实现
private static int function3(int[] array3){
int length = array3.length;
if (length <= 1) {
return 0;
}
for (int j : array3) {
if (j > length) {
return 0;
}
}
HashMap<Integer, Integer> check = new HashMap<Integer,Integer>();
for (int i : array3){
if(check.containsKey(i)){
return i;
}else{
check.put(i,1);
}
}
return 0;
}
//O(1)复杂度的实现
private static int function4(int[] array4){
int length = array4.length;
if (length <= 1) {
return 0;
}
for (int j : array4) {
if (j > length) {
return 0;
}
}
for (int i = 0; i < array4.length; i++) {
if(array4[i]!=i){
if(array4[i]==array4[array4[i]]){
return array4[i];
}else{
//这里要注意先令temp = array4[array4[i]],否则,再第三行赋值的时候会出问题
int temp = array4[array4[i]];
array4[array4[i]] = array4[i];
array4[i] = temp;
i--;
}
}
}
return 0;
}
}
题目二
/**
* 面试题3:数组中重复的数字
* 题目二:不修改数组找到重复的数字
* 在一个长度为n+1的数组里的所有数字都在1~n的范围内,所以数组中至少有一个数字是重复的。找出数组中任意一个重复的数字,但不能修改输入的数组
* 例如,如果输入长度为8的数组{2,3,5,4,3,2,6,7}那么对应的输出是重复的数字2或者3
*/
public class Array3_2 {
public static void main(String[] args) {
//测试用例的选择
//正常数组{2,3,1,0,2,5,3}
//不正常数组{2,4,1,0}
//无效数组{},{9,9}
int[] test1 = {2, 3, 1, 0, 2, 5, 3};
int[] test2 = {2, 3, 1, 0};
int[] test3 = {};
int[] test4 = {9, 9};
System.out.println(function2(test1));
System.out.println(function2(test2));
System.out.println(function2(test3));
System.out.println(function2(test4));
}
//辅助数组
private static int function1(int[] array1){
if(array1.length<=1){
return 0;
}
int[] arrayClone = new int[array1.length];
for (int j : array1) {
if(j>array1.length){
return 0;
}
if (arrayClone[j] != 0) {
return j;
} else {
arrayClone[j] = j;
}
}
return 0;
}
//二分查找思想
private static int function2(int[] arr){
int low = 1;
int high = arr.length - 1; // high即为题目的n
int mid, count;
while (low <= high) {
mid = ((high - low) >> 2) + low;
count = countRange(arr, low, mid);
if (low == high) {
if (count > 1)
return low;
else
break;
}
//判断条件的选取要慎之又慎
if (count > mid - low + 1) {
high = mid;
} else {
low = mid + 1;
}
}
return -1;
}
/**
* 返回在[low,high]范围中数字的个数
*/
public static int countRange(int[] arr, int low, int high) {
if (arr == null)
return 0;
int count = 0;
for (int a : arr) {
if (a >= low && a <= high)
count++;
}
return count;
}
}