几个有趣的操作
利用或操作|
和空格将英文字符转换成小写
// 可以变成小写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 := -1y := 2f := (x ^ y) < 0fmt.Println(f) // truem := 3n := 2z := (m ^ n) < 0fmt.Println(z) // false
临时交换两个数字
a := 1b := 2a ^= bb ^= aa ^= bfmt.Println(a)fmt.Println(b)
加1
n := 0n = -^nfmt.Println(n) // 1
减1
n := 0n = ^-nfmt.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 := 0for num != 0{num = num & (num - 1)count++}return count}
231. 2 的幂
func isPowerOfTwo(n int) bool {if n <= 0 {return false}// 如果一个数是2的幂次方,那么它的二进制中一定只有一个1return 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) / 2res := 0for i := 0; i < N; i++ {res += nums[i]}return sum - res}
思路4:异或运算
找缺失数、找出现一次数都是异或的经典应用。
我们可以先求得 (1,n)的异或和 ,然后用这个结果对各个数字进行异或。
这样最终得到的异或和表达式中,只有缺失元素出现次数为一次,其余元素均出现两次,即最终答案为缺失元素。
func missingNumber(nums []int) int {N := len(nums)ans := 0for i := 0; i <= N; i++ {ans ^= i}for i := 0; i < N; i++ {ans ^= nums[i]}return ans}