BFS 基础写法 —— 以 LeetCode #1091 Shortest Path in Binary Matrix 为例

Question

In an N by N square grid, each cell is either empty (0) or blocked (1).

clear path from top-left to bottom-right has length k if and only if it is composed of cells C_1, C_2, ..., C_k such that:

  • Adjacent cells C_i and C_{i+1} are connected 8-directionally (ie., they are different and share an edge or corner)
  • C_1 is at location (0, 0) (ie. has value grid[0][0])
  • C_k is at location (N-1, N-1) (ie. has value grid[N-1][N-1])
  • If C_i is located at (r, c), then grid[r][c] is empty (ie. grid[r][c] == 0).

Return the length of the shortest such clear path from top-left to bottom-right.  If such a path does not exist, return -1.

Example 1:

Input: [[0,1],[1,0]]


Output: 2

Example 2:

Input: [[0,0,0],[1,1,0],[1,1,0]]


Output: 4

Note:

  1. 1 <= grid.length == grid[0].length <= 100
  2. grid[r][c] is 0 or 1

解析

简单来说就是经典的BFS路径搜索,从左上角走到右下角,0是通路,1是障碍。

先给出最简洁的写法:

class Solution:
    def shortestPathBinaryMatrix(self, grid: List[List[int]]) -> int:
        n = len(grid)
        if grid[0][0] or grid[n-1][n-1]:
            return -1
        record = [(0,0,1)]
        for i, j, d in record:
            if i == n-1 and j == n-1: return d
            for x, y in ((i-1,j-1),(i-1,j),(i-1,j+1),(i,j-1),(i,j+1),(i+1,j-1),(i+1,j),(i+1,j+1)):
                if 0 <= x < n and 0 <= y < n and not grid[x][y]:
                    record.append((x, y, d+1))
                    grid[x][y] = 1
        return -1

用 record 这个list来记录状态,然后直接一边在后面不停加上下一层的记录,一边iterate

注意到 由于是BFS,采用将已经过的grid置为1来避免重复访问(BFS才能这样做)

即便如此简洁,此方法还是有一些问题,因此更好的方法为:

class Solution:
    def shortestPathBinaryMatrix(self, grid: List[List[int]]) -> int:
        if not grid or grid[0][0] or grid[-1][-1]:
            return -1

        m, n = len(grid), len(grid[0])
        front, end, level = set([(0, 0)]), set([(m-1,n-1)]), 1

        while front:

            # intersection
            if front & end:
                return level

            for x, y in front:
                grid[x][y] = 1

            front = set((x+dx, y+dy) for x, y in front for dx, dy in [(1,1),(1,-1),(-1,1),(-1,-1),(0,1),(0,-1),(-1,0),(1,0)] if 0<=x+dx<m and 0<=y+dy<n and grid[x+dx][y+dy]==0)

            level += 1

            if len(front) > len(end):
                front, end = end, front
        return -1
        

此方法解决了两个问题:

1. 更新每一层存的状态,减小内存空间

2. level只需一个变量存就够了(因为是BFS)

注意其采用了set而不用list,可以减少重复情况带来的重复计算

参考:

https://leetcode.com/problems/shortest-path-in-binary-matrix/discuss/312827/Python-Concise-BFS

原文地址:https://www.cnblogs.com/sbj123456789/p/12275446.html

时间: 2024-10-17 07:13:04

BFS 基础写法 —— 以 LeetCode #1091 Shortest Path in Binary Matrix 为例的相关文章

LeetCode 1293. Shortest Path in a Grid with Obstacles Elimination

原题链接在这里:https://leetcode.com/problems/shortest-path-in-a-grid-with-obstacles-elimination/ 题目: Given a m * n grid, where each cell is either 0 (empty) or 1 (obstacle). In one step, you can move up, down, left or right from and to an empty cell. Return

[LeetCode] 847. Shortest Path Visiting All Nodes 访问所有结点的最短路径

An undirected, connected graph of N nodes (labeled?0, 1, 2, ..., N-1) is given as?graph. graph.length = N, and?j != i?is in the list?graph[i]?exactly once, if and only if nodes?i?and?j?are connected. Return the length of the shortest path that visits

[LeetCode]Longest Increasing Path in a Matrix

题目:Longest Increasing Path in a Matrix Given an integer matrix, find the length of the longest increasing path. From each cell, you can either move to four directions: left, right, up or down. You may NOT move diagonally or move outside of the bounda

[LeetCode] 864. Shortest Path to Get All Keys 获得所有钥匙的最短路径

We are given a 2-dimensional?grid.?"."?is an empty cell,?"#"?is?a wall,?"@"?is the starting point, ("a",?"b", ...) are keys, and ("A",?"B", ...) are locks. We start at the starting poin

Clone Graph leetcode java(DFS and BFS 基础)

题目: Clone an undirected graph. Each node in the graph contains a label and a list of its neighbors. OJ's undirected graph serialization: Nodes are labeled uniquely. We use # as a separator for each node, and , as a separator for node label and each n

Dijkstra’s Shortest Path Algorithm / LeetCode 787. Cheapest Flights Within K Stops

Dijkstra’s Shortest Path Algorithm 实现详见:https://www.geeksforgeeks.org/dijkstras-shortest-path-algorithm-using-priority_queue-stl/ 需要注意的是,priority_queue并无法更新内部的元素,因此我们更新dist的同时,直接把新的距离加入pq即可.pq里虽然有outdated的dist,但是由于距离过长,他们并不会更新dist. // If there is sho

leetcode 934. Shortest Bridge

The algorithm for this problem is not so hard to figure out. This is a problem of finding the length of the shortest path in graph. As I mentioned in my previous article, BFS is a good way to slove this kind of problem. This problem is a little diffe

LeetCode --- 64. Minimum Path Sum

题目链接:Minimum Path Sum Given a m x n grid filled with non-negative numbers, find a path from top left to bottom right which minimizes the sum of all numbers along its path. Note: You can only move either down or right at any point in time. 这道题的要求是在m*n

【Leetcode】Minimum Path Sum

Given a m x n grid filled with non-negative numbers, find a path from top left to bottom right which minimizes the sum of all numbers along its path. Note: You can only move either down or right at any point in time. 思路:简单的动态规划题目,设f(m, n)为从(0, 0)到达(m