zoukankan      html  css  js  c++  java
  • 力扣111题、752题、773题(BFS)

    111、二叉树的最小深度

    基本思想:

    广度优先搜索

    具体实现:

    1、根节点入列

    2、循环条件是 直到清空队列

    3、节点出列以后判断左右子树

        如果左右子树都为空,返回现在的深度

        如果左孩子存在,加入队列,原深度加1

        如果右孩子存在,加入队列,原深度加1

      depth+1此时并不会改变depth

    代码:

    class Solution:
        def minDepth(self, root: TreeNode) -> int:
            if not root:
                return 0
    
            que = collections.deque([(root, 1)])
            while que:
                node, depth = que.popleft()
                if not node.left and not node.right:
                    return depth
                if node.left:
                    que.append((node.left, depth + 1))
                if node.right:
                    que.append((node.right, depth + 1))
            
            return 0

     套东哥框架

    class Solution:
        def minDepth(self, root: TreeNode) -> int:
            if not root:
                return 0
    
            que = collections.deque([root])
            depth = 1
            while que:
                for _ in range(len(que)):
                    node = que.popleft()
                    if not node.left and not node.right:
                        return depth
                    if node.left:
                        que.append(node.left)
                    if node.right:
                        que.append(node.right)
                depth += 1
            
            return depth

    752、打开转盘锁

    基本思想:

    广度优先算法

    具体实现:

    函数是顺序执行,遇到return语句或者最后一行函数语句就返回。而变成generator的函数,在每次调用next()的时候执行,遇到yield语句返回,再次执行时从上次返回的yield语句处继续执行。

    在最后一个for循环那就相当于执行next了。

    代码:

    class Solution:
        def openLock(self, deadends: List[str], target: str) -> int:
            def neighbors(node):
    for i in range(4): x = int(node[i]) for d in (-1, 1): y = (x + d) % 10 yield node[:i] + str(y) + node[i+1:] dead = set(deadends) queue = collections.deque([('0000', 0)]) seen = {'0000'} while queue: node, depth = queue.popleft() if node == target: return depth if node in dead: continue for nei in neighbors(node): if nei not in seen: seen.add(nei) queue.append((nei, depth+1)) return -1

    套东哥框架

    class Solution:
        def openLock(self, deadends: List[str], target: str) -> int:
            def turnup(s, i):
                s_list = list(s)
                if s_list[i] == '9':
                    s_list[i] = '0'
                else:
                    s_list[i] = str(int(s_list[i])+1)
                return "".join(s_list)
           
            def turndown(s, i):
                res = list(s) # 字符串变数列
                s_list = list(s)
                if s_list[i] == '0':
                    s_list[i] = '9'
                else:
                    s_list[i] = str(int(s_list[i])-1)
                return "".join(s_list)
            
            digits = "".join([str(x) for x in range(10)])+"0"
            n = 4
            
            start = "0"*n
            queue = deque([start])
            visited = set() #记录已经穷举过的密码
            visited.add(start)
            
            res = 0
            while queue:
                for _ in range(len(queue)):
                    combination = queue.popleft()
                    if combination in deadends:
                        continue
                    
                    if combination == target:
                        return res
                    for i in range(n): #四位数密码挨个开始转
                        tmp = turnup(combination, i)
                        if tmp not in visited:
                            queue.append(tmp)
                            visited.add(tmp)
                        tmp = turndown(combination, i)
                        if tmp not in visited:
                            queue.append(tmp)
                            visited.add(tmp)
                res += 1
            return -1

    773、滑动谜题

    基本思想:

    BFS

    具体实现:

    1、二维数组摊平变成一维数组

    创建一个数组,数组内元素的索引是0在一维数组中的位置

    数组内的元素,是0相邻数组在一维数组中的索引

     2、看0的位置和上下左右的数字进行交换

    代码:

    class Solution:
        def slidingPuzzle(self, board: List[List[int]]) -> int:
            neighbor = [[1,3],[0,2,4],[1,5],[0,4],[1,3,5],[2,4]]
            m, n = 2, 3
            start = ""
            target = "123450"
            step =0
    
            # 将2x3的数组转换成字符串
            for i in range(m):
                for j in range(n):
                    start += chr(board[i][j]+ord('0'))
    
            # BFS
            visited = []
            queue = collections.deque([start])
            while queue:
                sz = len(queue)
                for _ in range(sz):
                    cur = queue.popleft()
    
                    # 判断是否达到目标局面
                    if cur == target:
                        return step
                    i = 0
                    while(cur[i]!='0'): i+=1 #找到0的索引
                    #将数字0和相邻的数字交换位置
                    for adj in neighbor[i]:  #adj就是相邻数字的索引
                        new_board = list(cur) #当前字符串变成列表
                        new_board[adj], new_board[i] = new_board[i], new_board[adj]
                        new_board = "".join(new_board) #交换完以后将列表变成字符串
                        if(new_board not in visited): #防止交换到以前存在过的,防止走回头路
                            queue.append(new_board) 
                            visited.append(new_board)
                step +=1
            return -1

  • 相关阅读:
    Centos7
    appium+python常见报错(appium方面)
    python标准库之datetime
    python异常捕获
    python写入文件和读取文件
    python标准库之collections
    python导入类
    python3+robotframework+pycharm安装运行
    python 继承/父类和子类的关系
    python_类
  • 原文地址:https://www.cnblogs.com/zhaojiayu/p/14617929.html
Copyright © 2011-2022 走看看