题1:找出唯一成对的数
问题描述:
1~1000这1000个数放在含有1001个元素的数组T中,只有唯一的元素值重复,其他均只出现一次,每个数组元素只能访问一次,请设计一个算法,将重复的元素找出来,不用辅助存储空间.
解题思路:
一般思路:
过程:创建一个长度为N+1的arr数组——>对T数组进行遍历(arr[ T[ i ] ]++)——>对arr遍历,出现2则返回当前元素。
由题可知数据的范围内是1~1000,而且是连续的,这样我们可以利用数组下标的特性,创建一个长度为N+1的数组,其下标为元素值,进行统计。如果统计次数等于2说明该下标对应的元素是重复的
位运算思路:
过程:对T数组进遍历——》遍历的同时每个元素进行异或———》将异或的结果再次与1~1000异或————》所得的结果为重复的值
但是由于不能使用辅助空间,所以考虑位运算中 异或 ^ 的特点,A^A=0 A^0=A ,也就是说,两个相同的数字进行异或结果为0,可以用来消除重复。 可惜,题目要求寻找重复的值,所以,我们对这
1001个数字 加上(1~1000)这1000个数字,这样1~1000所有的数字出现了2次,可以消除,而那个重复的数字由于加了一次,变成了3次,A^A^A =A.。从而得出那个重复的A。
一般思路代码:
//一般思路 public static int f1(int[]T){ int res=-1; int[] arr=new int[1001]; //创建一个长度为N+1的数组 //对T数组遍历,将其值转换为arr数组的下标,并统计出现次数 for(int i=0;i<T.length;i++){ arr[T[i]]++; } //遍历arr数组,返回出现次数为2的下标 for(int i=0;i<arr.length;i++){ if(arr[i]==2){ res=i; } } return res; }
位运算思路代码:
//位运算方法 public static int f2(int[]T){ int res=0; //定义一个返回结果,初始值为0,因为A^0=A //先对T数组进行异或 for(int i=0;i<T.length;i++){ res^=T[i]; } //在与1~1000异或 for(int i=1;i<=1000;i++){ res^=i; } return res; }