第十届蓝桥杯 修改数组---并查集的简单应用--JAVA

第十届蓝桥杯 修改数组—并查集的简单应用–JAVA写法

题目

给定一个数组,数组中可能有重复的元素,现在要将其改为没有重复整数的数组。
修改方法:当修改第i个元素是,查看该元素之前是否出现过,如果出现过,会把第i个元素+1;如果还是重复继续+1。
输入格式:	第一行包含一个整数N
            第二行包含N个整数
  输出则把数组一次输出
  样例:5
        2 1 1 3 4
        输出:2 1 3 4 5

思路

一开始大部分人应该会想到递归,但是单纯的递归数据几百个可能就撑不住了,而这题的要求中数组元素最多会达到100000个
这题比较好的方法就是利用并查集,不过一般在考场上还是需要一定实力才能想到。没关系,编程就是慢慢积累经验的过程。

至于并查集建议大家看看csdn上其他大佬的详解(一定要看)

代码和讲解

大家捋不清楚的建议拿一组数据试一试
比如2 1 1 3 4,首先输出就是2,然后并查集使得数组元素f【2】本来的2,+1变成了3,也就是之后再碰到2会直接输出3。后面都是同理。一定要去看并查集的文章理解后再看代码。

public class Main6 {
////第十届研究生组试题G 修改数组(并查集应用)
	static int[] f=new int[2000000];
	public static void main(String[] args) {
		Scanner sc=new Scanner(System.in);
		//获取第一行数据
		int n=Integer.parseInt(sc.nextLine());
		int[] data=new int[n];
		
		//初始化f数组
		for (int i = 1; i < f.length; i++) {
			f[i]=i;
		}
		//获取第二行数据,放到数组中
		for (int i = 0; i < n; i++) {
			data[i]=sc.nextInt();
		}
		for (int i = 0; i < data.length; i++) {
			int k=find(data[i]);
			data[i]=k;
			f[data[i]]=find(data[i]+1);
		}
		for (int i = 0; i < data.length; i++) {
			System.out.print(data[i]+" ");
		}			
	}
	//(并查集)
	public static int find(int x) {
		if(x==f[x]) {
			return x;
		}else {
			f[x]=find(f[x]);
			return f[x];
		}
		
	
	}
	
	//以下是递归法,但是速度过慢,几十个数据就撑不住了
//	public static void fun(int k,ArrayList list) {
//		for (int i=k; k < list.size(); k++) {
//			boolean boo=false;
//			for (int j = 0; j 
//				if(list.get(i)==list.get(j)) {
//					list.set(i,list.get(i)+1);
//					boo=true;
//				}	
//			}
//			if(boo) {
//				fun(k, list);
//			}else {
//				k++;
//				fun(k, list);
//			}
//		}
//		
//	}
	
	
	
	
}

你可能感兴趣的:(第十届蓝桥杯 修改数组---并查集的简单应用--JAVA)