题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;
    }

 

posted @ 2020-03-28 21:10  木原纺  阅读(194)  评论(0编辑  收藏  举报