位运算相关算法题

相关题目

判断奇偶数
交换两个数
LintCode: 136. 只出现一次的数字
LintCode: 231. 2的幂
找出不大于n的最大的2的幂指数

相关知识点

异或

n ^ n = 0		// 两个相同的数异或之后结果为0
n ^ 0 = n		// 任何数与0异或之后结果为其本身

抑或运算支持交换律和结合律

(x ^ y) ^ y = x ^ (y ^ y) = x ^ 0 = x
x ^ (x ^ y) = (x ^ x) ^ y = 0 ^ y = y

判断奇偶数

判断一个数是奇数还是偶数

传统解法

模2取余,判断余数是否为1,余数为1则是奇数,否则为偶数
Java

public static boolean isOdd(int num) {
    return num % 2 == 1;
}

位运算解法

判断该数二进制表示中最后一位是否为1,为1则为奇数,否则为偶数
Java

public static boolean isOdd(int num) {
    return (num & 1) == 1;
}

交换两个数

传统做法

使用额外变量来交换两个数

int tmp = x;
x = y;
y = tmp;

位运算解法

不使用额外变量交换两个数

x = x ^ y		// (1)
y = x ^ y		// (2)
x = x ^ y		// (3)

把(1)中的x带入(2)中的x,有 y = x ^ y = (x ^ y) ^ y = x ^ (y ^ y) = x ^ 0 = x;
对于(3),把(2)中的y带入(3)中,推导如下:x = x ^ y = x ^ (x ^ y) = (x ^ x) ^ y = y

LintCode: 136. 只出现一次的数字

传统解法-哈希表

时间复杂度: O(n)
空间复杂度: O(n)

位运算解法

遍历数组,对所有数据进行异或操作,最后的结果便为只出现一次的数
时间复杂度:O(n)
空间复杂度:O(1)
原理:假设数组数据为: 1, 2, 3, 4, 5, 1, 2, 3, 4;利用抑或运算的交换律及结合律,对所有数据进行异或:
1 ^ 2 ^ 3 ^ 4 ^ 5 ^ 1 ^ 2 ^ 3 ^ 4 = (1 ^ 1) ^ (2 ^ 2) ^ (3 ^ 3) ^ (4 ^ 4) ^ 5 = 0 ^ 0 ^ 0 ^ 0 ^ 5 = 5 \

public static int findRepeat(int[] arr) {
    int tmp = arr[0];
    for (int i = 1; i < arr.length; i++) {
        tmp = tmp ^ arr[i];
    }
    return tmp;
}

LintCode: 231. 2的幂

传统解法

通过循环,让n个2连乘,最后结果便是2的n次幂

public static long powerOfTwo(int n) {
    int result = 1;
    for (int i = 0; i < n; i++) {
        result *= 2;
    }
    return result;
}

位运算解法

public static long powerOfTwo(int n) {
    int sum = 1;
    int tmp = 2;
    while (n != 0) {
        if ((n & 1) == 1) {
            sum *= tmp;
        }
        tmp *= tmp;
        n = n >> 1;
    }
    return sum;
}

你可能感兴趣的:(algorithm)