数据结构——数组(5)找出数组中唯一重复的数(元素范围1~1000)

这个题目本身就有一定局限性。比如,对于数组a[10001],其中,1000个数就是1~1000的每个数,可以任意排列,然后再多一个重复的数。题目就是怎么求出这个特殊的重复的数。
这一类问题的解决思路主要有以下几种:
方法一:先求和,再相减。即数组元素值求和,然后数组下标求和,然后二者相减,即可得到重复的数。

void xor_findDup1(int *a,int len)
{
    int sum1=0;
    int sum2=0;
    for(int i=0;i<len;i++)
    {
        sum2+=a[i];
    }
    for (int i=0;i<len;i++)
    {
        sum1+=i;
    }
    int num=sum2-sum1;
    cout<<"唯一重复的数为:"<<num<<endl;

}

方法二:异或法。a^a^b=b;a^a=0;a^b=1;0^b=b。该方法可先将数组元素异或,然后将下标异或,最后将两个异或结果异或,比如:a[1,2,3,4,2],下标为:[0,1,2,3,4]。异或最终只剩下0^2=2.

void xor_findDup2(int *a,int len)
{
    int i;
    int result =0;
    for(i=0;i<len;i++)
    {
        result ^=a[i];      //数组元素异或,保存结果到result
    }
    for (i=0;i<len;i++)
    {
        result^=i;              //result结果和数组下标序号异或,最终结果依然保存在result中
    }
    printf("重复数字为:%d\n",result);

}

方法三:位图法。即用一个位去记录数据的存放方式。不过,若数组长度为N,则需要N位。
这种方法的思路是,设立一个长度为N的标志数组,并初始化为false。然后遍历数组,每遍历一个数,在对应的i位置处记录该数标志位true,若已经是true了,说明这个数是重复的数。

void xor_findDup3(int *a,int len)
{
    int *arrFlag= (int *)malloc(len*sizeof(int));
    int i=1;
    while(i<len)
    {
        arrFlag[i] =false;
        i++;
    }

    for (i=0;i<len;i++)
    {
        if (arrFlag[a[i]]  ==false  )
            arrFlag[a[i]] =true;
        else
            printf("重复数字为:%d\n",a[i]);
    }

}

扩展 不是一个重复数字,而是多个重复数字的情况。
依然可以使用位图法,把重复的数字都输出即可。

猜你喜欢

转载自blog.csdn.net/zhangying_496/article/details/81185524