1.位运算--题1

题目

1-1000这1000个数放在含有1001个元素的数组中,只有唯一的一个元素重复,其它均只出现一次。每个数组元素只能访问一次,设计一个算法,将它找出来;不用辅助空间,能否实现。

算法

1.不需要辅助空间

注:因为知道不重复的其他数时哪些所以可以使用此方法,否则只能使用方法二

思路:

只有一个数是出现两次的,联想到 ^ 异或运算中,两个相同的数 异或 得到 0, 0 和任何一个数 异或 还等于这个数(即A^A=0,A^0=A)

设题目中的数组为 arr , 让 arr 与1-1000共1000个数 异或, 这样除了 arr 中重复了两次那个数得到保留外,其它的数均变为0,输出这个数即可

2.需要辅助空间

使用一个1001个元素的数组helper,helper[i] 记录数字 [i] 出现的次数,helper[i]==2i 即为要找的数

 

代码如下:

package 位运算;

import jdk.jshell.execution.Util;

import java.util.Random;

import java.util.*;

public class wei {

    public static void swap(int [] a,int x,int y)
    {
        int temp;
        temp=a[x];
        a[x]=a[y];
        a[y]=temp;
    }
    public static void main(String[] args)
    {
        int N=1001;
        int [] arr=new int[N];
        for(int i=0;i<arr.length-1;i++)
        {
            arr[i]=i+1;
        }
        //最后一个数是随机数
        arr[arr.length-1]=new Random().nextInt(N-1)+1;//nextInt函数作用:该方法的作用是生成一个随机的int值,该值介于[0,n)的区间,随机int值在包含0而不包含n区间内。
       //随即下标
        int Index=new Random().nextInt(N);
        //交换最后一个下标上的数到随机下标位置
        swap(arr,Index,arr.length-1);
        System.out.println(Arrays.toString(arr));//打印数组的方法
        
        System.out.println("====不建立辅助空间====");
        //异或消除重复
        int x1=0;
         for(int i=1;i<=N-1;i++)
         {
             x1=(x1^i);//1-1000个数异或
         }

         for(int i=0;i<N;i++)
         {
             x1=x1^arr[i];//1-1000个数再与arr中的数异或,得出重复的数
         }
         System.out.println(x1);
         System.out.println("======建立辅助空间的方法=====");
         //利用辅助数组的下标代表出现的次数
         int[ ] helper=new int[N];
         for(int i=0;i<N;i++)
         {
             helper[arr[i]]++;
         }
         for(int i=0;i<N;i++)
         {
             if(helper[i]==2)
             {System.out.println(i);
               break;}
            
         }
    }
}

 

运行结果:

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章