算法技巧:位运算 逻辑运算

一、位运算

n&(n-1)作用:将n的二进制表示中的最低位为1的改为0。

先看一个简单的例子: n = 10100(二进制),则(n-1) = 10011 ==》n&(n-1) = 10000 可以看到原本最低位为1的那位变为0。 弄明白了n&(n-1)的作用,那它有哪些应用?

1. 求某一个数的二进制表示中1的个数 while (n >0 ) { count ++; n &= (n-1); }

2. 判断一个数是否是2的方幂 n > 0 && ((n & (n - 1)) == 0 )

二、逻辑运算

求 1+2+...+n ,要求不能使用乘除法、for、while、if、else、switch、case等关键字及条件判断语句(A?B:C)。

class Solution {
    public int sumNums(int n) {
        boolean flag = (n>0)&&(n+=sumNums(n-1))>0;
        return n;
    }
}

通常实现递归的时候我们都会利用条件判断语句来决定递归的出口,但由于题目的限制我们不能使用条件判断语句,那么我们是否能使用别的办法来确定递归出口呢?答案就是逻辑运算符的短路性质。

以逻辑运算符 && 为例,对于 A && B 这个表达式,如果 A 表达式返回 extit{False}False ,那么 A && B 已经确定为 extit{False}False ,此时不会去执行表达式 B。同理,对于逻辑运算符 ||, 对于 A || B 这个表达式,如果 A 表达式返回 extit{True}True ,那么 A || B 已经确定为 extit{True}True ,此时不会去执行表达式 B。

利用这一特性,我们可以将判断是否为递归的出口看作 A && B 表达式中的 A 部分,递归的主体函数看作 B 部分。如果不是递归出口,则返回 extit{True}True,并继续执行表达式 B 的部分,否则递归结束。当然,你也可以用逻辑运算符 || 给出类似的实现,这里我们只提供结合逻辑运算符 && 的递归实现。

原文地址:https://www.cnblogs.com/jingpeng77/p/13097925.html