给定正整数 n,找到若干个完全平方数(比如 1, 4, 9, 16, ...
)使得它们的和等于 n。你需要让组成和的完全平方数的个数最少。
示例 1:
输入: n = 12
输出: 3
解释: 12 = 4 + 4 + 4.
示例 2:
输入: n = 13
输出: 2
解释: 13 = 4 + 9.
思路比较简单,利用一个队列
+BFS
即可解决,但要注意计算复杂度的问题,之前忘记添加vistied
集合,导致计算数值较大时复杂度激增,增加后有效可以改善,当然还有很多种方法可以更容易的解决问题(动态规划,我还没看过相关知识点,先放着这把囧),贴上我的解决方案:
class Solution:
def numSquares(self, n: int) -> int:
def Maxsquare(n):
Max=int(n**0.5)
Max_queue=[int(i**2) for i in range(1,Max+1)]
return Max_queue
Max_queue=Maxsquare(n)
queue=[]
vistied=set()
queue.extend(Max_queue)
for i in Max_queue:
vistied.add(i)
count=1
if n in Max_queue:
return 1
while queue:
count+=1
size=len(queue)
for i in range(size):
front=queue.pop(0)
for j in Max_queue:
new=front+j
if new==n:
return count
if new>n or new in vistied:
continue
queue.append(new)
vistied.add(new)
你有一个带有四个圆形拨轮的转盘锁。每个拨轮都有10个数字:'0', '1', '2', '3', '4', '5', '6', '7', '8', '9'
。每个拨轮可以自由旋转:例如把 ‘9’ 变为 ‘0’,‘0’ 变为 ‘9’ 。每次旋转都只能旋转一个拨轮的一位数字。
锁的初始数字为 '0000'
,一个代表四个拨轮的数字的字符串。
列表 deadends
包含了一组死亡数字,一旦拨轮的数字和列表里的任何一个元素相同,这个锁将会被永久锁定,无法再被旋转。
字符串target
代表可以解锁的数字,你需要给出最小的旋转次数,如果无论如何不能解锁,返回 -1。
示例 1:
输入:deadends = [“0201”,“0101”,“0102”,“1212”,“2002”], target = “0202”
输出:6
解释:
可能的移动序列为 “0000” -> “1000” -> “1100” -> “1200” -> “1201” -> “1202” -> “0202”。
注意 “0000” -> “0001” -> “0002” -> “0102” -> “0202” 这样的序列是不能解锁的,
因为当拨动到 “0102” 时这个锁就会被锁定。
将if new in (deadendset or vistied)
改为if new in deadendset or new in vistied:
后性能大增?
仍然是标准的BFS+队列
解决方案,贴上代码
#BFS
class Solution:
def openLock(self, deadends: List[str], target: str) -> int:
deadendset=set(deadends)
queue=[]
vistied=set()
vistied.add('0000')
queue.append('0000')
if '0000' in deadendset:
return -1
if target in deadendset:
return -1
count=0
while queue:
count+=1
size=len(queue)
for k in range(size):
front=queue.pop(0)
for i in range(4):
for j in [-1,1]:
#new=[i for i in front ] #这里是别人的选择下一步状态的代码,用到了ord,chr函数
#new[i]=chr((ord(new[i])-ord('0')+j+10)%10+ord('0'))
#new=''.join(new)
#new=front[:i]+str(new_num)+front[(i+1):]
new_num=(int(front[i])+j+10)%10
new=front[:i]+str(new_num)+front[(i+1):]
if new in deadendset or new in vistied:
continue
if new==target:
return count
queue.append(new)
vistied.add(new)
return -1