Leetcode之位运算总结

这篇文章总结目前我做过的位运算相关习题,在之后的刷题过程中将会不断扩充此专题。题目列表如下:
1. 190 颠倒的二进制位
2. 191 位1的个数
3. 231 2的幂
4. 371 两整数之和
5. 405 数字转化为十六进制

190 颠倒的二进制位

题目大意

颠倒给定的 32 位无符号整数的二进制位。
示例1

输入: 00000010100101000001111010011100
输出: 00111001011110000010100101000000
解释: 输入的二进制串 00000010100101000001111010011100 表示无符号整数 43261596,
因此返回 964176192,其二进制表示形式为 00111001011110000010100101000000。

示例2

输入:11111111111111111111111111111101
输出:10111111111111111111111111111111
解释:输入的二进制串 11111111111111111111111111111101 表示无符号整数 4294967293,
因此返回 3221225471 其二进制表示形式为 10101111110010110010011101101001。

思路

利用位运算,原数每次循环右移1位,取末尾数字,然后新数加上这个末尾再循环左移。

代码

 public int reverseBits(int n) {
        int t = 0;
        for(int i = 0;i<32;i++) 
            t+= (1&(n>>i))<<(31-i);
        return t;
    }

运行时间2ms。

位1的个数

题目大意

编写一个函数,输入是一个无符号整数,返回其二进制表达式中数字位数为 ‘1’ 的个数。
示例1

输入:00000000000000000000000000001011
输出:3
解释:输入的二进制串 00000000000000000000000000001011 中,共有三位为 '1'。

示例2

输入:00000000000000000000000010000000
输出:1
解释:输入的二进制串 00000000000000000000000010000000 中,共有一位为 '1'。

思路一:位运算

利用循环右移操作,每次移动1位,并且取出末尾与1做&操作,若不为1,说明末尾是0。

public int hammingWeight(int n) {
         int cnt = 0;
        for(int i=0;i<32;i++)
        {
            cnt += n&1;
            n >>=1;
        }
        return cnt;
    }

思路二:n与n-1做位运算

当n与n-1做&运算,会把最后一个1的位变成0。


image.png
 public int hammingWeight(int n) {
        int cnt = 0;
        while(n!=0) {
           ++cnt;
           n = n&(n-1);
        }
        return cnt;
    }

运行时间2ms。

231 2的幂

题目大意

给定一个整数,编写一个函数来判断它是否是 2 的幂次方。
示例1

输入: 1
输出: true
解释: 2^0 = 1

示例2

输入: 16
输出: true
解释: 24 = 16

方法一:暴力法

采用迭代的方法,一个一个试。此题会超时。

public boolean isPowerOfTwo(int n) {
        if(n==1) return true;
        int cur = 1;
        while(cur<n) {
            cur *=2;
            if(cur==n) return true;
        }
        return false;
    }

方法二:二分查找

采用打表和二分查找的方法,将int范围内的所有2^n全部存入一个整数表中,然后对整数表进行二分查找。

int[] res = new int[31];
private void form() {
        res[0] = 1;
        for(int i=1;i<31;i++)
            res[i]=res[i-1]*2;
    }
public boolean isPowerOfTwo(int n) {
        form();
        if(n!=1 && n%2==1) return false;
        int low = 0;
        int high = 30;
        while(low<high) {
            int mid = (low+high)>>1;
            if(res[mid]==n) return true;
            else if(res[mid] > n)
                high = mid -1;
            else if(res[mid] < n)
                low = mid+1;
        }
        return res[low]==n?true:false;
    } 

运行时间3ms,87.42%。

方法三:位运算

将2^n 和 2^n-1做与运算,结果一定为0。

 public boolean isPowerOfTwo(int n) {
        if(n<=0) return false;
        return (n&(n-1))==0?true:false;
    }

运行时间2ms, 98.23%。

两整数之和

题目大意

不使用运算符 + 和 - ​​​​​​​,计算两整数 ​​​​​​​a 、b ​​​​​​​之和。
示例1

输入: a = 1, b = 2
输出: 3

输入: a = -2, b = 3
输出: 1

思路

不用运算符,考虑位运算。a^b 得到不考虑进位的a+b结果;a&b<<1得到a+b的进位。


image.png
public int getSum(int a, int b) {
        while(b!=0) {
            int carry = (a&b)<<1;
            a = a^b;
            b = carry;
        }
        return a;
    }

405 数字转化为十六进制

题目大意

给定一个整数,编写一个算法将这个数转换为十六进制数。对于负整数,我们通常使用补码运算。
注意

十六进制中所有字母(a-f)都必须是小写。
十六进制字符串中不能包含多余的前导零。如果要转化的数为0,那么以单个字符'0'来表示;对于其他情况,十六进制字符串中的第一个字符将不会是0字符。
给定的数确保在32位有符号整数范围内。
不能使用任何由库提供的将数字直接转换或格式化为十六进制的方法。

示例1

输入:
26

输出:
"1a"

示例2

输入:
-1

输出:
"ffffffff"

方法:位运算

public String toHex(int num) {
        if(num==0) return "0";
        char[] dict = {'0','1','2','3','4','5','6','7','8','9',
            'a','b','c','d','e','f'};
        StringBuffer sb = new StringBuffer();
        while(num!=0) {
            sb.append(dict[num&0xf]);
            num = num >>> 4;
        }
        return sb.reverse().toString();
    }

&0xf: 取末尾四位。
运行时间1ms,击败88.12%。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 219,366评论 6 508
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,521评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 165,689评论 0 356
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,925评论 1 295
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,942评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,727评论 1 305
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,447评论 3 420
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,349评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,820评论 1 317
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,990评论 3 337
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,127评论 1 351
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,812评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,471评论 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,017评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,142评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,388评论 3 373
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,066评论 2 355

推荐阅读更多精彩内容

  • 5月12日,第十一天。 7.薇薇:英语听力半小时,安工听课两节。今天爸比带阿宝一起去烧烤。
    灸灸微笑阅读 181评论 0 0
  • 自9月底开始,儿子感冒、咳嗽, 我感冒、咳嗽,奶奶感冒、咳嗽,都在反反复复,儿子去医院三次,我昨晚彻底败下阵来,今...
    朱珠在路上阅读 1,397评论 10 10
  • 《弟子规》新解4:【出则悌】篇 或饮食,或坐走。长者先,幼者后。 长呼人,即代叫。人不在,己即到。 我刚工作那会儿...
    格致教练蒋海涛阅读 1,708评论 0 4