位运算常用技巧以及练习

几个有趣的操作

  • 利用或操作|和空格将英文字符转换成小写

    	// 可以变成小写
    	i := 'a' | ' '
    	fmt.Printf("%c\n", i)
    	j := 'A' | ' '
    	fmt.Printf("%c\n", j)
    
  • 利用与操作&和下划线把英文字符转换成大写

    	// 可以变成大写
    	m := 'b' & '_'
    	n := 'B' & '_'
    	fmt.Printf("%c\n", m)
    	fmt.Printf("%c\n", n)
    
  • 大小写转换

    	// 可以大小写转换
    	a := 'd' ^ ' '
    	b := 'D' ^ ' '
    	fmt.Printf("%c\n", a)
    	fmt.Printf("%c\n", b)
    
  • 判断两个数是否异号

    	x := -1
    	y := 2
    	f := (x ^ y) < 0
    	fmt.Println(f) // true
    
    	m := 3
    	n := 2
    	z := (m ^ n) < 0
    	fmt.Println(z) // false
    
  • 临时交换两个数字

    	a := 1
    	b := 2
    	a ^= b
    	b ^= a
    	a ^= b
    	fmt.Println(a)
    	fmt.Println(b)
    
  • 加1

    	n := 0
    	n = -^n
    	fmt.Println(n) // 1
    
  • 减1

    	n := 0
    	n = ^-n
    	fmt.Println(n) // -1
    

n & (n - 1)的运用

作用:消除数字n的二进制表示中的最后一个1

在这里插入图片描述
本图借用了labuladong算法,特此声明

其核心逻辑就是,n - 1 一定可以消除最后一个 1,同时把其后的 0 都变成 1,这样再和 n 做一次 & 运算,就可以仅仅把最后一个 1 变成 0 了。

练习

191. 位1的个数

func hammingWeight(num uint32) int {
    count := 0
    for num != 0{
        num = num & (num - 1)
        count++
    }
    return count
}

231. 2 的幂

func isPowerOfTwo(n int) bool {
    if n <= 0 {
        return false
    }
    // 如果一个数是2的幂次方,那么它的二进制中一定只有一个1
    return n & (n - 1) == 0
}

a ^ a = 0的运用

一个数和它本身的异或运算结果为0,即a ^ a = 0;一个数和0做异或运算的结果为它本身,即a ^ 0 = a

练习

136. 只出现一次的数字

func singleNumber(nums []int) int {
    N := len(nums)
    res := nums[0]
    for i := 1; i < N; i++ {
        res = res ^ nums[i]
    }
    return res
}

268. 丢失的数字

  • 思路1:排序

  • 思路2:HashSet

  • 思路3:等差数列

    func missingNumber(nums []int) int {
        N := len(nums)
        sum := (0 + N) * (N + 1) / 2
        res := 0
        for i := 0; i < N; i++ {
            res += nums[i]
        }
        return sum - res
    }
    
  • 思路4:异或运算

    找缺失数、找出现一次数都是异或的经典应用。

    我们可以先求得 (1,n)的异或和 ,然后用这个结果对各个数字进行异或。

    这样最终得到的异或和表达式中,只有缺失元素出现次数为一次,其余元素均出现两次,即最终答案为缺失元素。

    func missingNumber(nums []int) int {
        N := len(nums)
        ans := 0
        for i := 0; i <= N; i++ {
            ans ^= i
        }
        for i := 0; i < N; i++ {
            ans ^= nums[i]
        }
        return ans
    }
    
  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

胡桃姓胡,蝴蝶也姓胡

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值