学习目标:
通过LeetCode编程练习,坚持21天每日一题,提高编程水平。
学习内容:
题目内容:
给定正整数 N ,我们按任何顺序(包括原始顺序)将数字重新排序,注意其前导数字不能为零。
如果我们可以通过上述方式得到 2 的幂,返回 true;否则,返回 false。
1 <= N <= 10^9
思路:
拆分成两个子问题:
①判断一个整数是否为 2 的幂。
②枚举可能包含重复字符的数组的全排列。
第一个问题首先想到的是将得到的数跟1-10^9范围内所有2的幂进行比对,但是比较麻烦,后来查找资料,发现一种快捷的方法。
# 按位与判断一个数是否是2的幂
def isPowerOfTwo(n: int) -> bool:
return (n & (n - 1)) == 0
第二个问题还是运用昨天学到的回溯算法,递归搜索全排列。
重点:排列问题,一般有个标记数组,标记回溯过的数字。
#标记数组,下标为已经使用过的数字。初始化为全0
used = [False] * m
难点:递归进入下一层的条件。
if(num == 0 and ch == '0') or used[i] or (i > 0 and not used[i - 1] and ch == nums[i - 1]):
continue
学习产出:
# 按位与判断一个数是否是2的幂
def isPowerOfTwo(n: int) -> bool:
return (n & (n - 1)) == 0
class Solution:
def reorderedPowerOf2(self, n: int) -> bool:
#将数字存放在数组中,先转成str再放入数组。
nums = sorted(list(str(n)))
m = len(nums)
#标记数组,下标为已经使用过的数字。初始化为全0
used = [False] * m
def backtrack(idx: int, num: int) -> bool:
#回溯出口,
if idx == m:
return isPowerOfTwo(num)
for i, ch in enumerate(nums):
#不能有前导零
if(num == 0 and ch == '0') or used[i] or (i > 0 and not used[i - 1] and ch == nums[i - 1]):
continue
used[i] = True
if backtrack(idx + 1, num * 10 + ord(ch) - ord('0')):
return True
used[i] = False
return False
return backtrack(0, 0)