唯一成对的数(算法很美)

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

解法一:显然已经有人提出了一个比较精彩的解法,将所有数加起来,减去1+2+…+1000的和。这个算法已经足够完美了,相信出题者的标准答案也就是这个算法,唯一的问题是,如果数列过大,则可能会导致溢出。

解法二:异或就没有这个问题,并且性能更好。将所有的数全部异或,得到的结果与1231000的结果进行异或,得到的结果就是重复数。

public class 唯一成对的数 {
    public static void main(String[] args){
        int N = 11;
        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;
        //随机下标
        int index = new Random().nextInt(N);
        Util.swap(arr,index,arr.length-1);
        Util.print(arr);
        int x1 = 0;
        //对于任何数x,都有x^x=0,x^0=x,同自己求异或为0,同0求异或为自己
        for(int i=1;i<= N-1; i++){
            x1 = (x1^i);
        }
        for(int i = 0; i < N;i++){
            x1 = x1^arr[i];
        }
        System.out.println();
        System.out.println(x1);
        System.out.println("============有辅助空间");
        (2)
        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;
            }
        }
    }
}

异或的作用:

  • 判断奇偶性
  • 获取二进制位是1还是0(两种解决方案)
  • 交换两个整数变量的值
  • 不用判断语句,求整数的绝对值

(1)判断奇偶性

//这个实际考的不多, 太简单
//思路:奇数的二进制最低为一定为1,偶数的二进制最低位一定为0,
a^1==1?偶数:奇数

(2)获取二进制位是1还是0

当两个数的二进制表示,进行异或运算时,当前位的二进制表示不同则为1,相同则为0。

即:

    0 ^ 0 = 01 ^ 0 = 10 ^ 1 = 1;

    1 ^ 1 = 0;

按位异或的3个特点:
(10异或任何数 = 任何数;
(21异或任何数 = 任何数取反;
(3)任何数异或自己 = 把自己置0;
按位异或的几个常见用途:
(1)使某些特定的位翻转
    例如对数10100001 的第2位和第3位翻转,则可以将该数与00000110进行按位异或运算。
                    10100001 ^ 00000110 = 101001112) 实现两个值的交换,而不必使用临时变量。
    例如交换两个整数a = 10100001, b = 00000110的值, 可通过下列语句实现:
        a = a ^ b;            //a = 10100111
        b = b ^ a;            //b = 10100001
        a = a ^ b;            //a =  00000110
即等效于以下两步:
  ① 执行前两个赋值语句:“a=a∧b;”和“b=b∧a;”相当于b=b∧(a∧b)。而b∧a∧b等于a∧b∧b(异或满足交换律,结合律)。b∧b的结果为0,因为同一个数与本身相∧,结果必为0。因此b的值等于a∧0,即a,其值为3。
  ② 再执行第三个赋值语句:a=a∧b。由于a的值等于(a∧b),b的值等于(b∧a∧b),因此,相当于a=a∧b∧b∧a∧b,即a的值等于a∧a∧b∧b∧b,等于b。
  a得到b原来的值

(3)交换两个整数变量的值

//交换a、b的值
a=a^b
b=a^b
a=a^b

1.借助第三个变量来实现

C=A;A=B;B=C;

2.利用加减法实现两个变量的交换

 A=A+B;B=A-B;A=A-B;

3.用位异或运算来实现,也是效率最高的

原理:一个数异或本身等于0 ;异或运算符合交换律

A=A^B;B=A^B;A=A^B

(4)不用判断语句,求整数的绝对值

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值