869.重新排序得到 2 的幂

143 阅读1分钟

题目:
给定正整数 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)
}