leetcode--single_number&&single_number_II

33 篇文章 0 订阅
27 篇文章 0 订阅

single_number

题意: 给定一个整数类型数组,除了一个元素之外其他所有元素均出现两次,找出这个唯一的元素。
条件: 要求线性时间复杂度,并且不适用额外空间
分析: 本题非常经典,在《剑指offer》中也出现过,用到的方法是位运算中的异或操作。记录每一bit出现的次数。由于两个相同的整数做异或一定是0,所以数组中重复的整数异或之后也是0,遍历数组时两两异或,最后异或后的结果就是那个唯一值。(该方法非常经典,要牢记)

代码

public int singleNumber(int[] A) {
        if(A == null){
            return Integer.MIN_VALUE;
        }else{
            int length = A.length;
            int result = 0;
            for(int i = 0; i < length; i++){
                result ^= A[i];
            }
            return result;
        }
}

源程序下载

single_number_II

题意: 给定一个整数类型数组,除了一个元素之外其他所有元素均出现三次,找出这个唯一的元素。
条件: 要求线性时间复杂度,并且不适用额外空间
分析: 由于本题重复值出现三次,不能直接使用异或操作。既然一个二进制位不够,那我们不妨用两个二进制位来表示出现次数。为此,定义几个变量 one , two , three , one 表示某个位只出现一次, two 表示某个位出现过两次, three=one & two , three 主要用来归零,只要出现过三次,就将 one two 改为0(和single_number不同的是,single_number出现两次就归零,所以异或可以完成,single_number_II出现三次归零)。最后返回 one 即可。(该方法同样非常巧妙,抓住了该题的本质)

代码

public int singleNumber(int[] A) {
        if(A == null){
            return Integer.MIN_VALUE;
        }else{
            int one = 0;    //出现过一次的位
            int two = 0;    //出现过两次的位
            int three = 0;  //出现过三次的位
            for(int i = 0; i < A.length; i++){
                int a = A[i];
                two |= one&a;   //先修改two
                one ^= a;       //再修改one
                three = one&two;    //one和two相应位置都是1的表示出现过3次
                one &= ~three;     //出现过3次的位在one和two中都修正回0
                two &= ~three;
            }
            return one;
        }
}

源程序下载

single_number改

题意: 给定一个整数类型数组,除了两个元素之外其他所有元素均出现两次,找出这个唯一的元素。本题将只有一个唯一的编程有两个唯一的,其余均出现过两次
分析: 本题依然先用异或,但是异或后的结果是两个数叠加后的值,这该如何求解?异或后的结果是一个32位的整数(JAVA中int是32位),从最后一位开始向左找到第一个1出现的位置,那么这两个数在该位(bit)上的值一定不同(否则就变为0),那么可以根据这一位是0或者1将数组一分为二,前一个数组在该位上均是0,后一个数组载该位上均是1; 两个唯一的值肯定一个在前一个数组中,一个在后一个中。然后分别对两个数组求异或,两个数组中的唯一值都只有一个了,就变成single_number问题了!(how unimaginable we can solve problem use this way, and it is crazy who can come up with this settlement!),原谅我自己也没实现这个方法,读者自行解决吧~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值