2.数组a[N]中,随机存放了1至N-1的数,再加入一个数,这个数和之前的n-1其中某个数重复。写一个函数,找出被重复的数字.时间复杂度必须为o(N



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);*/
            
    }  
 
}  


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值