java算法-位运算

136. 只出现一次的数字

java算法-位运算_第1张图片

解答:

/**
     * 异或运算有以下三个性质:
     *
     * ·任何数和 0做异或运算,结果仍然是原来的数,即 a ⊕ 0 = a。
     * ·任何数和其自身做异或运算,结果是 0,即 a ⊕ a = 0。
     * ·异或运算满足交换律和结合律,即 a⊕b⊕a = b⊕a⊕a = b⊕(a⊕a) = b⊕0 = b。
     *
     * 利用上面的性质,假设数组中有 2m+1 个数,其中有 m 个数各出现两次,一个数出现一次,
     * 则数组中的全部元素的异或运算结果即为数组中只出现一次的数字
     *
     * */
    public int singleNumber(int[] nums) {
        int res = 0;
        for (int num : nums) {
            res ^= num;
        }
        return res;
    }

剑指 Offer 56 - I. 数组中数字出现的次数(260. 只出现一次的数字 III)

java算法-位运算_第2张图片

解答:
java算法-位运算_第3张图片

public int[] singleNumbers(int[] nums){
        int x = 0;
        for (int num : nums) {
            x ^= num;
        }
        int[] res = new int[2];
        int bit = 1;
        while ((x&bit) == 0) bit = bit << 1;
        for (int num : nums) {

            if ((num&bit)!=0){
                res[0] ^= num;
            }else {
                res[1] ^= num;
            }
        }
        return res;
    }

137. 只出现一次的数字 II

java算法-位运算_第4张图片

//思路1:统计每一位1的个数,然后模3及为结果对应位的值
public int singleNumber(int[] nums) {
        long bit = 1;
        int res = 0;
        while(bit <= (1L<<31)){
            int sum = 0;
            for (int num : nums) {
                sum += (num&bit)/bit;
            }
            res += (sum%3)*bit;
            bit = bit<<1;
        }
        return res;
    }
// 思路2:状态机 或 电路原理解题
	public int singleNumber(int[] nums) {
        int x=0,y=0;
        for (int z : nums) {
            y = ~x &(y^z);
            x = ~y & (x^z);
        }
        return y;
    }

法2需利用真值表推出表达式,具体思路参考:逻辑电路角度详细分析该题思路,可推广至通解
java算法-位运算_第5张图片

你可能感兴趣的:(算法)