前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >LeetCode-算法-位运算-第14天

LeetCode-算法-位运算-第14天

作者头像
布衣者
发布2021-09-07 11:39:41
3110
发布2021-09-07 11:39:41
举报
文章被收录于专栏:布衣者博客

190. 颠倒二进制位

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

示例 1: 输入: 00000010100101000001111010011100 输出: 00111001011110000010100101000000 解释: 输入的二进制串 00000010100101000001111010011100 表示无符号整数 43261596, 因此返回 964176192,其二进制表示形式为 00111001011110000010100101000000。 示例 2: 输入:11111111111111111111111111111101 输出:10111111111111111111111111111111 解释:输入的二进制串 11111111111111111111111111111101 表示无符号整数 4294967293, 因此返回 3221225471 其二进制表示形式为 10111111111111111111111111111111 。 示例 1: 输入:n = 00000010100101000001111010011100 输出:964176192 (00111001011110000010100101000000) 解释:输入的二进制串 00000010100101000001111010011100 表示无符号整数 43261596, 因此返回 964176192,其二进制表示形式为 00111001011110000010100101000000。 示例 2: 输入:n = 11111111111111111111111111111101 输出:3221225471 (10111111111111111111111111111111) 解释:输入的二进制串 11111111111111111111111111111101 表示无符号整数 4294967293, 因此返回 3221225471 其二进制表示形式为 10111111111111111111111111111111 。

具体题目链接

Python

代码语言:javascript
复制
class Solution:
    def reverseBits(self, n: int) -> int:
        rev=0
        for i in range(0,32):
            rev|=(n&1)<<(31-i)
            n >>= 1
        return rev

思路:for i in range(0,32)表示循环次数32次。(n&1)之前了解过,只保留当前n最右侧一位,(n&1)<<(31-i),的意思是将最右侧一位左移(31-i)。此时rev按位|与,从而使最高位获取到n最右侧一位。同理,第二次循环则是左侧第二位获取n的右侧第二位。 这里以8位的二进制,则相对应的为(n&1)<<(7-i)来举个例子: 第一次循环n=181二进制1011 0101,n&1=0000 0001,通过左移位7位,可以看出变为1000 0000,此处的1是1011 0101的最后一位的1。最后rev 0000 0000 与1000 0000按位与,则rev=1000 0000。之后n=n>>1=0101 1010。 第二次循环n&1=0000 0000通过左移7-i=6位,则变为0000 0000,最后与rev 1000 0000按位与则rev=1000 0000,n=n>>1=0010 1101。最终通过循环结束得到rev为1010 1101。

GO

代码语言:javascript
复制
func reverseBits(num uint32) uint32 {
    // for i:=0;i<32;i++{
    //     k|=(num&1)<<(31-i)
    //     num>>=1
    // }
    // return k
    var m1 uint32=0x55555555 // 01010101010101010101010101010101
    var m2 uint32=0x33333333 // 00110011001100110011001100110011
    var m4 uint32=0x0f0f0f0f // 00001111000011110000111100001111
    var m8 uint32=0x00ff00ff // 00000000111111110000000011111111
    // var m16 uint32=0x0000ffff
    num=((num>>1)&m1)|((num&m1)<<1)
    num=((num>>2)&m2)|((num&m2)<<2)
    num=((num>>4)&m4)|((num&m4)<<4)
    num=((num>>8)&m8)|((num&m8)<<8)
    return num>>16|num<<16
}

思路:分治法,看到这个思路着实给我当头一击,还能这样玩。 我先简单整理一下思路,以整数为例。刚开始为 12345678,通过奇数位与偶数位互换则变为21436587 再通过两个两个互换得到43218765 再通过四个四个互换得到87654321 这里采用8位的数字演示一下,方便理解。此时定义,num=191,二进制位1011 1111(思路:二进制是从左向右看)

代码语言:javascript
复制
    var m1 uint32=0b01010101
    var m2 uint32=0b00110011
    var m4 uint32=0b00001111

先解释一下每一步的作用,以m1举例: num=((num>>1)&m1)|((num&m1)<<1) (num>>1)=0101 1111使二进制向右挪动一位,则第一位变为第二位,第二位变成第三位依次类推,实现挪位。 (num>>1)&m1=0101 0101,因为m1是奇数位0,偶数位1,则在进行&操作,只会保留(num>>1)偶数位。 (num&m1)=0001 0101,同理也是只保留num的偶数位。 (num&m1)<<1=0010 1010,因为已知(num&m1)保留了偶数位,通过<<1(左移一位)是其变为只保留奇数位。

因此((num>>2)&m1)|((num&m1)<<2)=0111 1111,此时与1011 1111对比发现,奇偶互换。 同理,num=((num>>2)&m2)|((num&m2)<<2)则等于1101 1111 同理,num=((num>>4)&m4)|((num&m4)<<4)则等于1111 1101 此时num就变为倒序二进制num,因此32位同理,只是增加了8位互换,和16位互换。为什么最后只有 return num>>16|num<<16,而不是像m1 m2一样。原因:因为uint32最高也就32位,也就是左移和右移16位,都会保留下来需要的16位,其余全部为0。而对于python则必须像m1 m2那样,因为python会在左移16位后扩充到int变为64位,使结果错误,因此需要采用限制。

136. 只出现一次的数字

给定一个非空整数数组,除了某个元素只出现一次以外,其余每个元素均出现两次。找出那个只出现了一次的元素。

示例 1: 输入: [2,2,1] 输出: 1 示例 2: 输入: [4,1,2,1,2] 输出: 4

具体题目链接

Python

代码语言:javascript
复制
class Solution:
    def singleNumber(self, nums: List[int]) -> int:
        return functools.reduce(lambda x,y:x^y,nums)

思路:这里采取官网的三个性质。 1.任何数和 0做异或运算,结果仍然是原来的数,即 a^0=a^0=a。 2.任何数和其自身做异或运算,结果是0,即 a^a=0。 3.异或运算满足交换律和结合律,即 a ^b^a=b^a^a=b^(a^a)=b^0=b。 有了以上性质题目就很好理解了,我们至于要按顺序左异或即可,最终结果就是一个的元素。

GO

代码语言:javascript
复制
func singleNumber(nums []int) int {
    t:=0
    for _,k:=range nums{
        t^=k
    }
    return t
}

思路:见python性质。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2021年08月15日,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 190. 颠倒二进制位
    • Python
      • GO
      • 136. 只出现一次的数字
        • Python
          • GO
          领券
          问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档