题目:
给定正整数 n ,我们按任何顺序(包括原始顺序)将数字重新排序,注意其前导数字不能为零。
如果我们可以通过上述方式得到 2 的幂,返回 true;否则,返回 false。
算法:
方法一:回溯+二进制
思路:将每个位置的数拆成数组进行排列,通过二进制方法检查排列得到的数字的二进制表示是否只有一个1
func reorderedPowerOf2(n int) bool {
nums := []byte(fmt.Sprintf("%d", n))
length := len(nums)
visited := make([]bool, len(nums))
var backtrack func(index, num int) bool
backtrack = func(index, num int) bool {
if index == length {
return isPowerOf2(num)
}
for i := range nums {
if visited[i] || (num == 0 && nums[i] == '0') {
continue
}
visited[i] = true
if backtrack(index + 1, num * 10 + int(nums[i] - '0')) {
return true
}
visited[i] = false
}
return false
}
return backtrack(0, 0)
}
func isPowerOf2(num int) bool {
return num & (num - 1) == 0
}
方法二:打表
先统计[0-1e9]中每个2的幂次[0-9]出现的次数,放到hashmap中,如果n的[0-9]出现的次数存在map中,则可以“重新排序得到 2 的幂”。如何将“[0-9]出现的次数”作为hashmap的key?
func reorderedPowerOf2(n int) bool {
powerOf2Map := make(map[string]bool)
for i := 1; i <= 1000000000; i = i << 1 {
powerOf2Map[getKey(i)] = true
}
return powerOf2Map[getKey(n)]
}
func getKey(n int) string {
key := make([]byte, 10)
for n > 0 {
key[n % 10] ++
n = n / 10
}
return string(key)
}