要求 是不修改数组
所以像上一道题一样就无法对数组进行改变之后了。
第一种
想到的还是建立一个哈希表,然后通过取值的方式看看这个哈希表
package question3_find_repeat_number_without_change;
import java.util.HashMap;
/**
* @Classname Solution1
* @Description TODO
* @Date 2020/3/6 16:26
* @Created by mmz
*/
public class Solution1 {
public static int solution(int[] arr){
HashMap<Integer,Integer> map = new HashMap<Integer, Integer>();
for(int i = 0;i<arr.length;++i){
if(map.get(arr[i]) == null){
map.put(arr[i],i);
}else{
return arr[i];
}
}
return 0;
}
public static void main(String[] args) {
int[] arr = new int[]{2,3,5,4,3,2,6,7};
System.out.println(Solution1.solution(arr));
}
}
第二种
是一种二分查找的方式
我们把从1n的数字从中间的数字m分成两部分,前面一半为1m后面一半为m+1~n,如果1
到m的数字的数目超过m,那么这一半的区间里面一定包含着重复的数字;否则,另一半的区间里一定包含重复的数字,这个过程和二分查找算法很类似,只是多了一步统计区里的数字的数目。
package question3_find_repeat_number_without_change;
/**
* @Classname Solution2
* @Description TODO
* @Date 2020/3/6 20:01
* @Created by mmz
*/
public class Solution2 {
public int solution2(int[] arr){
if(arr == null || arr.length < 0){
return -1;
}
for(int a: arr){
if(a < 1 || a>arr.length-1){
return -1;
}
}
int low = 1;
int high = arr.length-1;
int mid,count;
while(low<=high){
mid = ((high - low)>>2)+low;
count = countRange(arr,low,high);
if(low == high){
return low;
}
if(count > mid -low +1){
high = mid;
}else{
low = mid +1;
}
}
return -1;
}
public 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;
}
public static void main(String[] args) {
int[] arr = new int[]{2,7,5,7,3,2,6,7};
System.out.println(Solution1.solution(arr));
}
}
用到了二分法