LeetCode刷题日记19-5-3

297.完全平方数

题目描述:

给定正整数 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)

752.打开转盘锁

你有一个带有四个圆形拨轮的转盘锁。每个拨轮都有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

你可能感兴趣的:(LeetCode,LeetCode)