题目描述:

给定范围 [m, n],其中 0 <= m <= n <= 2147483647,返回此范围内所有数字的按位与(包含 m, n 两端点)。

示例 1:

输入: [5,7]
输出: 4

示例 2:

输入: [0,1]
输出: 0

要完成的函数:

int rangeBitwiseAnd(int m, int n)

说明:

1、这道题给定两个int型整数,一个是开端,一个是末端,要求把开端和末端之间的数每一个都进行“与”操作,返回最后的结果。

2、这道题肯定不是直接做一个循环,每一个都去“与”一遍,这样子太费时间。我们要从数位的角度来考虑,因为数位只有32位,更加好操作。

如果只有两个数字,那么最后一位必然要改变,肯定一个是0,一个是1,那么与的结果肯定是0。

如果只有三个数字,那么最后一位和倒数第二位必然要改变,因为最后一位只能存储两个数字,三个数字的话必然倒数第二位也要改变,那么这时候倒数两个数字与的结果肯定是0。

如果有五个数字,那么最后一位、倒数第二位和倒数第三位必然要改变,因为最后两位只能存储四个数字,五个数字的话必然倒数第三位也要改变,所以最后三位与的结果肯定是0。

所以我们可以得出规律:

最后一位只能存储两个数,所以如果有三个数字,那么必然倒数第二位和最后一位为0。

倒数两位只能存储四个数,所以如果有五个数字,那么必然倒数三位都为0。

倒数三位只能存储八个数,所以如果有九个数字,那么必然倒数四位都为0。

……

所以我们可以根据给出来的开端和末端,计算出中间一共有多少个数,对应地找一下应该倒数几位都为0。

比如5是0101,7是0111,中间有三个数字5/6/7,那么必然倒数两位都是0,所以最终结果是0100。

这道题到这里看起来似乎是解决了,但其实我们只解决了其中一种情况。

还是上面这个例子,我们有三个数字,所以最后一位和倒数第二位都会改变,但是倒数第三位会不会改变呢?甚至倒数第四位会不会改变呢?

我们来看一下:

0100

0101

0110

0111

-------

1000

1001

如果从0100开始,到0110结束,三个数字,倒数两位是必须改变的,倒数第二位必须0和1都有出现,然后相与为0,但是倒数第三位,由于这个时候没有发生进位,所以没有影响,我们只需要考虑倒数两位的改变。

但是如果从0110开始,到1000结束呢,同样三个数字,同样的倒数两位必须改变,因为倒数两位的变化还是10->11->00,必然还是出现0和1,导致相与结果为0,但是这个时候前面几位却发生了进位,导致相与的结果不能是0100,而是0000。

这时候有一种很直觉的做法,就是把开端和末端两个数字“与”一下,接着再做上面的操作——找到倒数几位必须要改为0。

这种操作可以ac所有的测试样例,要解释的话也不难(不感兴趣原因的同学直接看代码啦),比如7和9

00111

01001

这两个是“跨域”的操作,三个数照理来说只有倒数两位要改变,前面的三位是不应该变化的(如果在同一个域中),由于倒数第二位产生了进位符号,传递给了倒数第三位,导致产生了前后两种不同的前三位的表示。开端和末端的前三位的表示可以代表两种不同的状态,并且所有中间值的前三位只有这两种状态,不应该再改变了。

这样解释可能比较难以理解,不懂的同学自己举一些需要“跨域”的例子,比如有三个数的,五个数的,甚至九个数的,多想想应该也就会比较清楚。

代码如下:(附详解)

    int rangeBitwiseAnd(int m, int n)
{
if(m==n)return m;//边界情况,开端和末尾是同一个数,直接返回
if(m==0)return 0;//边界情况,开端是0,相与必然为0,直接返回0
int geshu=n-m,t=log10(geshu)/log10(2)+1,t1=t;//t表示倒数的几位要置零,t1记录一下t的值
m=m&n;//开端“与”末尾,预防“跨域”的情况
while(t--)//把倒数t位置零,先不断右移
m>>=1;
while(t1--)//再不断左移
m<<=1;
return m;//返回m
}

上述代码实测24ms,beats 97.21% of cpp submissions。

leetcode-201-数字范围按位与的更多相关文章

  1. C#版 - Leetcode 201. 数字范围按位与(bitwise AND) - 题解

    C#版 - Leetcode 201. 数字范围按位与(bitwise AND) - 题解 在线提交: https://leetcode.com/problems/bitwise-and-of-num ...

  2. LeetCode 201. 数字范围按位与(Bitwise AND of Numbers Range)

    201. 数字范围按位与 201. Bitwise AND of Numbers Range 题目描述 给定范围 [m, n],其中 0 <= m <= n <= 214748364 ...

  3. Java实现 LeetCode 201 数字范围按位与

    201. 数字范围按位与 给定范围 [m, n],其中 0 <= m <= n <= 2147483647,返回此范围内所有数字的按位与(包含 m, n 两端点). 示例 1: 输入 ...

  4. leetcode 201. 数字范围按位与 解题报告

    给定范围 [m, n],其中 0 <= m <= n <= 2147483647,返回此范围内所有数字的按位与(包含 m, n 两端点). 示例 1: 输入: [5,7] 输出: 4 ...

  5. [LeetCode] 201. Bitwise AND of Numbers Range ☆☆☆(数字范围按位与)

    https://leetcode.com/problems/bitwise-and-of-numbers-range/discuss/56729/Bit-operation-solution(JAVA ...

  6. 201 Bitwise AND of Numbers Range 数字范围按位与

    给定范围 [m,n],其中 0 <= m <= n <= 2147483647,返回此范围内所有数字的按位与(包含m, n两端点).例如,给定范围 [5,7],您应该返回 4. 详见 ...

  7. [Swift]LeetCode201. 数字范围按位与 | Bitwise AND of Numbers Range

    Given a range [m, n] where 0 <= m <= n <= 2147483647, return the bitwise AND of all numbers ...

  8. Leetcode201. Bitwise AND of Numbers Range数字范围按位与

    给定范围 [m, n],其中 0 <= m <= n <= 2147483647,返回此范围内所有数字的按位与(包含 m, n 两端点). 示例 1: 输入: [5,7] 输出: 4 ...

  9. LeetCode 201 Bitwise AND of Numbers Range 位运算 难度:0

    https://leetcode.com/problems/bitwise-and-of-numbers-range/ [n,m]区间的合取总值就是n,m对齐后前面一段相同的数位的值 比如 5:101 ...

  10. LeetCode——翻转数字

    第七题,Reverse Integer.(https://leetcode.com/problems/reverse-integer/description/) 注意事项:翻转之后,数据有可能会超过I ...

随机推荐

  1. redis的连接方法|连接池|操作

    1.先看下redis的连接 import redis # 连接服务端 r = redis.Redis(host="127.0.0.1",port=6379) #获取所有的key值 ...

  2. 配置Linux防火墙

    配置防火墙(服务器安全优化)(转) 安全规划:开启 80  22 端口并 打开回路(回环地址 127.0.0.1) # iptables –P INPUT ACCEPT # iptables –P O ...

  3. Mysql快速重置root密码

    以Mac版本为例 首先关闭mysql服务 然后新建一个Terminal 1.输入 sudo /usr/local/mysql/bin/mysqld_safe --skip-grant-tables 2 ...

  4. app开发中如何利用sessionId来实现服务端与客户端保持回话

    app开发中如何利用sessionId来实现服务端与客户端保持回话 这个问题太过于常见,也过于简单,以至于大部分开发者根本没有关注过这个问题,我根据和我沟通的开发者中,总结出来常用的方法有以下几种: ...

  5. Monocular Visual-Inertial Odometry单目视觉惯性里程计

    Monocular Visual-Inertial Odometry:https://www.qualcomm.com/invention/research 单目视觉-惯性里程计 INDOOR POS ...

  6. 在spark中启动standalone集群模式cluster问题

    spark-submit --master spark://master:7077 --deploy-mode cluster --driver-cores 2 --driver-memory 100 ...

  7. handsontable-developer guide-data binding,data sources

    数据绑定: 1.表格中得数据是引用了数据源中的数据:表格中数据改变,数据源中得数据也改变:数据源中得数据改变,通过render方法,表格中的数据也改变: 2.如果想把数据源中的数据和表格中的数据分开: ...

  8. FIREDAC的TFDJSONDataSets和TFDJSONDeltas查询和提交数据

    服务端代码: uses Data.FireDACJSONReflect, FireDAC.Stan.Storage, FireDAC.Stan.StorageBin, FireDAC.Stan.Sto ...

  9. Python入门基础学习 二

    Python入门基础学习 二 猜数字小游戏进阶版 修改建议: 猜错的时候程序可以给出提示,告诉用户猜测的数字偏大还是偏小: 没运行一次程序只能猜测一次,应该提供多次机会给用户猜测: 每次运行程序,答案 ...

  10. [C#]获取当前程序运行路径的方法集合(转)

    //获取当前进程的完整路径,包含文件名(进程名).string str = this.GetType().Assembly.Location;result: X:\xxx\xxx\xxx.exe (. ...