package com.hanwei;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Random;
import java.util.Scanner;
import java.util.Set;
/*
*
* 2.数组a[N]中,随机存放了1至N-1的数,再加入一个数,这个数和之前的n-1其中某个数重复。写一个函数,找出被重复的数字.时间复杂度必须为o(N
*/
public class tes {
public boolean fun(int n) {
int k=n-1;
int object[]=new int[n];
int object1[]=new int[n];
Set<Integer> set=new HashSet();
int randomnum=0;
boolean t=true;
Random ran=new Random();
//为了方便我随机数就不一一输入数组中了,用随机函数来生成,为了验证算法,真正的题目随机数组
for(int i=0;i<n;) {
randomnum=ran.nextInt(k)+1;
if(set.add(randomnum)) {
object[i++]=randomnum;//放入1---n-1不重复的随机数
}else if(n>3&&t) {
object[i++]=randomnum;//放入1---n-1不重复的随机数
System.out.println("重复的数是:"+randomnum);
t=false;//控制产生的随机数1---n-1中只有一个重复的
}else if(n==2) {
object[i++]=randomnum;
System.out.println("重复的数是:"+randomnum);
}else if(n==3&&i<2) {//放入1---2不重复的随机数到数组大小为3中 第二个重复
object[i++]=randomnum;
System.out.println("重复的数是:"+randomnum);
}else if(n==3&&i==2&&object[i-1]!=randomnum) {//放入1---2不重复的随机数随机数到数组大小为3中 去除三个重复的情况
object[i++]=randomnum;
System.out.println("重复的数是:"+randomnum);
}
}
for(int i=0;i<n;i++) {//输出数组检查是否1--n-1中只有一个数重复
System.out.println(object[i]);
}
System.out.println("不重复的数有"+set.size()+"个");
if(k==1) {//只有两个数时 把1---1的数放入一个数组大小为2的数组中,其中某个数重复一次,那么重复的数不需要再找就是1
System.out.println("重复的数是:"+object[0]);
}else if(k==2) {//只有3个数时 把1---2的数放入一个数组大小为3的数组中,其中某个数重复一次,那么重复的数就是1或者2,做一次判断即可
if(object[0]==object[1]||object[0]==object[2]) {
System.out.println("重复的数是:"+object[0]);
}else {
System.out.println("重复的数是:"+object[1]);
}
}else if(k>3&&set.size()==n-1) {//找出重复数
//下面的算法复杂度就是n
/* //1.常规的两重for循环的简化
brek:
for(int j=0,i=j+1;j<n;i++) {
if(i>=n) {
++j;
i=j+1;
}else if(object[j]==object[i]) {
System.out.println("算法1重复的数是:"+object[j]);
break brek;
}
}*/
//2.思路,1--n之间的n个数中有两个重复全部加起来和1--(n-1)中的n-1个数全部累加起来相差的的数就是重复的随机数
int s=0;
int r=0;
for(int i=0;i<n;i++) {
s+=object[i];//1--n之间的n个数之和,s中包括了重复的一个数字
r+=i;//1---(n-1)之间的n-1个数字之和,r中没有包括重复的一个数字
}
System.out.println("算法2重复的数是:"+(s-r));
}
//3.思路3,从头到尾检查并放在一个有序数组里面,对应的数放入到自己的位置
for(int i=0;i<n;i++) {
int a;//用来临时存放上一次从数组拿出来的数
int b;//中介数
if(object[i]==i+1){//对应的数在对应位置那么就继续往下
continue;
}
else {
a=object[i];
object[i]=-1;
while(a!=object[a-1]&&(a-1)<n){
if(object[a-1]==-1)
break;
b=object[a-1];
object[a-1]=a;
a=b;
}
if(a==object[a-1]) {
System.out.println("算法3重复的数是:"+a);
break;
}
}
}
return false;
}
public int fun() {
return 0;
}
public static void main(String args[]){
int n=0;
Scanner scn=new Scanner(System.in);
System.out.println("请输入数组的大小");
n=scn.nextInt();
if(n>1)
new tes().fun(n);
/* Random ran=new Random();
System.out.println(ran.nextInt(1)+1);*/
}
}