奇妙的位运算(二)

上篇的链接为:http://www.cnblogs.com/jiu0821/p/4677184.html

这次是偶然看到一个题目,很好玩,便记在这里吧!

Bitwise AND of Numbers Range

给出一个范围,[m, n](0 <= m <= n <= 2147483647),返回这些数字的与运算结果。

直接逐个做与运算,TLE,我们得发现高效解法。

我们把[0, 15]用二进制码表示出来:

0 0 0 0
0 0 0 1
0 0 1 0
0 0 1 1
0 1 0 0
0 1 0 1
0 1 1 0
0 1 1 1
1 0 0 0
1 0 0 1
1 0 1 0
1 0 1 1
1 1 0 0
1 1 0 1
1 1 1 0
1 1 1 1

仔细看,几个连续的二进制码肯定会有相同的前缀(前缀长度可能为0),除了相同的前缀外,将之后的各位置为0即为所求。如何求解这个相同前缀?只需要m和n同时右移,直到两数相等为止:

 1 class Solution {
 2 public:
 3     int rangeBitwiseAnd(int m, int n) {
 4         int t=0;
 5         while(m!=n){
 6             m>>=1;
 7             n>>=1;
 8             t++;
 9         }
10         return m<<t;
11     }
12 };

或者:

1 class Solution {
2 public:
3     int rangeBitwiseAnd(int m, int n) {
4         if(m==n)    return m;
5         int t=rangeBitwiseAnd(m>>1,n>>1);
6         return t<<1;
7     }
8 };

还有一种更巧妙的方法,将n的最右边的 1 bit 置为0,直到值不大于m即可:

1 class Solution {
2 public:
3     int rangeBitwiseAnd(int m, int n) {
4         while(m<n)  n&=n-1;
5         return n;
6     }
7 };
时间: 2024-08-06 03:44:19

奇妙的位运算(二)的相关文章

奇妙的位运算

三道leetcode上的题目. Single Number Given an array of integers, every element appears twice except for one. Find that single one. 题意即:一个数组,里面的元素每个都出现了两次,除了一个特殊的,求这个特殊元素.接触过这类题目的coder很快能够脱口而出:直接异或就ok了!因为两个相同的数异或会抵消每个bit位,结果为0. 1 class Solution { 2 public: 3

nyist oj 138 找球号(二)(hash 表+位运算)

找球号(二) 时间限制:1000 ms  |  内存限制:65535 KB 难度:5 描述 在某一国度里流行着一种游戏.游戏规则为:现有一堆球中,每个球上都有一个整数编号i(0<=i<=100000000),编号可重复,还有一个空箱子,现在有两种动作:一种是"ADD",表示向空箱子里放m(0<m<=100)个球,另一种是"QUERY",表示说出M(0<M<=100)个随机整数ki(0<=ki<=100000100),分

剑指offer—算法之位运算(二进制中1的个数)

位运算: 左移:m<<n将m左移n位,左移后低位补充0: 右移:m>>n将m右移n位,右移后高位补充的是符号位,负数补充1,整数补充0.(正数的边界值为(1,ox7FFFFFFF),负数的边界值为(ox80000000,oxFFFFFFFF)) 题目一:请实现一个函数,输入一个整数,输出这个数的二进制表示中1的个数. 思路一:将二进制数i与1相与,判断是否为1,然后将tag=1左移一位得到tag=2,然后再与i相与,循环结束的条件是tag==0:该算法的时间复杂度为输入的i的位数.

位运算简介及实用技巧(二):进阶篇(1)[转]

位运算简介及实用技巧(二):进阶篇(1) 原贴链接:http://www.matrix67.com/blog/archives/264 =====   真正强的东西来了!   ===== 二进制中的1有奇数个还是偶数个    我们可以用下面的代码来计算一个32位整数的二进制中1的个数的奇偶性,当输入数据的二进制表示里有偶数个数字1时程序输出0,有奇数个则输出1.例如,1314520的二进制101000000111011011000中有9个1,则x=1314520时程序输出1.var   i,x,

位运算应用之二——大小写转换

问题描述: 试编写一个程序,将输入的大写字母转换为小写字母,输入的小写字母转换为大写字母,要求用位运算完成转换过程 算法分析: 我们都知道大写字母A~Z的编码是65~90,小写字母的编码a~z是97~112:而大写A(65)的二进制编码为100 0001,小写字母a(97)的二进制编码为110 0001,很明显除了第5位之外其它位都是一样的,也就是说大小写是由第5位来区分的,第5位为1即为小写,第5位为0即为大写. 算法描述: 1 /* 2 *问题描述:试编写一个程序,将输入的大写字母转换为小写

Java千问:Java位运算经典应用(二)

接上篇 三.不借助中间变量交换两个变量的值 通常情况下,我们要交换两个变量的值都按如下步骤操作: 这种操作方式不难理解,实现交换变量值的关键点就在于中间变量c.而现在的题目要求是不借助中间变量来交换a和b的值.如果不使用位运算的方式,同样可以做到不借助中间变量交换两个变量的值,其实现过程如下. 为了讲解方便,我们把最初a与b的值称之为原始a和原始b,3行代码就是3步操作:第1步:把原始a与原始b相加的和存储到变量a中,变量b的值暂时没有发生变化.第2步:用这个和减去原始b,再赋值到变量b中,经过

位运算总结&amp;拾遗

JavaScript 位运算总结&拾遗 最近补充了一些位运算的知识,深感位运算的博大精深,此文作为这个系列的总结篇,在此回顾下所学的位运算知识和应用,同时也补充下前文中没有提到的一些位运算知识. 把一个数变为大于等于该数的最小的2的幂 一个数为2的幂,那么该数的二进制码只有最高位是1. 根据这个性质,我们来举个栗子,比如有数字10,转为二进制码后为: 1 0 1 0 我们只需把 0 bit的位置全部用1填充,然后再把该二进制码加1就ok了.而x | (x + 1)正好可以把最右边的0置为1,可是

Java I/O : Bit Operation 位运算

Writer      :BYSocket(泥沙砖瓦浆木匠) 微         博:BYSocket 豆         瓣:BYSocket FaceBook:BYSocket Twitter    :BYSocket 泥瓦匠喜欢Java,文章总是扯扯Java. I/O 基础,就是二进制,也就是Bit. 一.Bit与二进制 什么是Bit(位)呢?位是CPU处理或者数据存储最小的单元.类似于很小很小的开关,一开一关,表示为1或者0.所以,这就是计算机处理任何数据的"细胞",要谨记.

位运算和关于两个数交换的多种方法

我们知道,位运算在计算中有着广泛的应用. 在计算机的各种编程语言中位运算也是一种不可缺少的运算,尤其是在计算机的底层实现代码中. 以下我们就来介绍一下位运算. 1.左移运算<<  左移右移都是移动二进制数 0000-0000 0000-0000 0000-0000 0000-1100     =12 向左移动一位变为(右边缺几位就补几个0) 0000-0000 0000-0000 0000-0000 0001 1000       =24 再向左移一位 0000-0000 0000-0000