正如kaya3在其注释中提到的那样,您可以使用元组而不是列表,而不是使用整数位集,因为它们是不可变且可哈希的。在元组中设置一些位会更加复杂,因此一旦您在函数内部,将元组转换为列表可能会更容易。
如果您真的想使用位集,则必须使用2的幂进行一些ANDing,ORing和XORing。
在长度为 n 的位集中的索引 i 处设置位:
bitset = bitset | 2**(n-1-i)
重设一点:
bitset = bitset & (2**n-1) ^ 2**(n-1-i)
,
您可以使用元组或位元组。使用元组的最简单方法是将其转换为数组,然后再转换回它,但是,将值数组切片并传递而不是传递布尔数组更快。
这是三种方法:
- 元组切片无布尔数组(388毫秒),这是最快的,因为您可以通过检查最后一项来提早退出
- 使用位集(532毫秒)
- 从列表转换为元组(624毫秒)
元组切片:
def canIWin(self,n: int,target: int) -> bool:
@lru_cache(None)
def isWin(nums,target):
if target <= 0:
return False
n = len(nums)
if nums[-1] >= target:
return True
for i in range(n):
if not isWin(nums[:i] + nums[i + 1:],target - nums[i]):
return True
return False
if target < 2:
return True
if (n + 1) * n / 2 < target:
return False
return isWin(tuple(range(1,n + 1)),target)
位集:
def canIWin(self,target: int) -> bool:
isNthBitSet = lambda x,n: (x & (1 << n) != 0)
setNthBit = lambda x,n: x | (1 << n)
@lru_cache(None)
def isWin(isUsed,target):
if target <= 0:
return False
for i in reversed(range(n)):
if not isNthBitSet(isUsed,i):
if not isWin(setNthBit(isUsed,i),target - i - 1):
return True
return False
if target < 2:
return True
if n * (n + 1) / 2 < target:
return False
return isWin(0,target)
列出元组:
def canIWin(self,target: int) -> bool:
@lru_cache(None)
def isWin(isUsed,target):
isUsed = list(isUsed)
if target <= 0:
return False
for i in reversed(range(1,n + 1)):
if not isUsed[i - 1]:
if i >= target:
return True
isUsed[i - 1] = True
if not isWin(tuple(isUsed[::]),target - i):
return True
isUsed[i - 1] = False
return False
if target < 2:
return True
if n * (n + 1) / 2 < target:
return False
return isWin(tuple([False] * n),target)
本文链接:https://www.f2er.com/3048905.html