342. 4的幂-E
label: 位运算
给定一个整数 (32 位有符号整数),请编写一个函数来判断它是否是 4 的幂次方。
示例 1:
输入: 16
输出: true
示例 2:
输入: 5
输出: false
进阶:
你能不使用循环或者递归来完成本题吗?
分析:
因为4的幂次方相当于每次乘4,即做移两位,所以4的幂次方,只有一个1,且1在正确的位置上,4的幂次方正确的位置全部填1为0x55555555;1的个数可以用最右这个1和原数异或,结果为0说明这个数只有一个1(当时也想用相与的方式,但若左边还有1,则会因为与0相与而为0,所以不能用与),是否在正确位置上,只需判断和0x5555555相与的结果是否和其本身相等;另外这个数不能是0,因为0满足上述两个规则,最后将这三个规则放在一起即可确定是否是4的幂次方。
另外不用循环的办法是制作32位中所有的4次幂的表,因为总过32/2=16,也不大,每次一个数做与操作16次即可判断出来。
还有就是统计是否只有一个1,这个1是否在奇数为上。
package main
import "fmt"
/*
执行用时 :4 ms, 在所有 Go 提交中击败了47.13%的用户
内存消耗 :2.2 MB, 在所有 Go 提交中击败了11.43%的用户
*/
func isPowerOfFour_table(num int) bool {
k4 := []int{
1,
4,
16,
64,
256,
1024,
4096,
16384,
65536,
262144,
1048576,
4194304,
16777216,
67108864,
268435456,
1073741824,
}
return k4[0]^num == 0 || k4[1]^num == 0 || k4[2]^num == 0 || k4[3]^num == 0 ||
k4[4]^num == 0 || k4[5]^num == 0 || k4[6]^num == 0 || k4[7]^num == 0 ||
k4[8]^num == 0 || k4[9]^num == 0 || k4[10]^num == 0 || k4[11]^num == 0 ||
k4[12]^num == 0 || k4[13]^num == 0 || k4[14]^num == 0 || k4[15]^num == 0
}
/*
执行用时 :0 ms, 在所有 Go 提交中击败了100.00%的用户
内存消耗 :2.2 MB, 在所有 Go 提交中击败了11.43%的用户
*/
func isPowerOfFour_loop(num int) bool {
if num==0{
return false
}
tmp:=num
cnt:=0
for tmp%2==0{
cnt+=1
tmp>>=1
}
if cnt%2==0&&tmp==1{
return true
}else{
return false
}
}
/*
执行用时 :0 ms, 在所有 Go 提交中击败了100.00%的用户
内存消耗 :2.2 MB, 在所有 Go 提交中击败了60.00%的用户
*/
func isPowerOfFour(num int) bool {
tmp:=^(num-1)&num//last right 1
return tmp>0&&tmp^num==0&&tmp&(0x55555555)==tmp
}
func main() {
tables := []int{
0,1, 3, 4, 8, 16, 9, 64, 32, 1073741824, 1073741825,
}
for _, v := range tables {
fmt.Println(isPowerOfFour(v))
}
}