An interview question: find the direction of first step

Viewed 35

Description of the problem is below:

Given the matrix of M rows and N columns, 0 represents empty space,- 1 represents obstacle, and 1 represents target points (there are multiple target points).

For each empty space, if you want to reach a target point at the shortest distance, please mark the direction of the first step.

If starting up, you should mark the point as 2. if starting down , you should mark the point as 3. if starting left , you should mark the point as 4. if starting right , you should mark the point as 5.

The priority of direction is up, down, left and right from big to small, that is, if you can reach the target point with the shortest distance from a point up or down, you are supposed to start up.

Returns the matrix after marking. 0< m, n< 1000

I tried to wrote solution in python, but always get 'TypeError: 'NoneType' object is not iterable'. Really don't know why. I would really appreciate your help if you can point out the problem!

My basic idea is, for each empty cell, find its nearest target using BFS. then by specifying this empty cell as start and this nearest target as destination, i find out the direction of the first step. Code might not be so concise, thanks for your time and effort!

class Solution:
    """
    @param grid: the input matrix
    @return: the new matrix
    """
    grid = None
    def shortestPath(self, grid):
        # BFS
        self.grid = grid.copy()
        m = len(grid)
        n = len(grid[0]) if m > 0 else 0
        res = [[None] * n for _ in range(m)]

        for i in range(m):
            for j in range(n):
                if grid[i][j] not in [-1, 1]:
                    tarx, tary, step = self.bfs(i, j)
                    res[i][j] = self.search(i, j, tarx, tary)
                else:
                    res[i][j] = grid[i][j]

        return res

    def search(self, i, j, tarx, tary):
        dic = {0: 2, 1: 3, 2: 4, 3: 5}
        dirs = [[-1, 0], [1, 0], [0, -1], [0, 1]]
        min_dist = float('inf')
        direction = -1

        for idx, d in enumerate(dirs):
            x, y = i + d[0], j + d[1]
            if x == tarx and y == tary:
                return dic[idx]

            if self.inside(x, y):
                arr = [tarx, tary]
                _, __, dist = self.bfs(x, y, arr)
                if min_dist > dist:
                    min_dist = dist
                    direction = dic[idx]

        return direction

    def bfs(self, i, j, target = None):
        m = len(self.grid)
        n = len(self.grid[0]) if m > 0 else 0
        visit = [[False] * n for _ in range(m)]
        visit[i][j] = True
        dirs = [[-1, 0], [1, 0], [0, -1], [0, 1]]
        qu = [(i, j, 0)]

        while len(qu) > 0:
            ti, tj, step = qu[0][0], qu[0][1], qu[0][2]
            qu.pop()

            for d in dirs:
                x, y = ti + d[0], tj + d[1]
                if self.inside(x, y) and not visit[x][y]:
                    if not target:
                        if self.grid[x][y] == 1:
                            return x, y, step + 1
                    else:
                        tarx, tary = target[0], target[1]
                        if x == tarx and y == tary:
                            return x, y, step + 1

                    visit[x][y] = True
                    qu.append((x, y, step + 1))

    def inside(self, x, y):
        if 0 <= x < len(self.grid) and 0 <= y < len(self.grid[0]) and self.grid[x][y] != -1:
            return True
        return False

if __name__ == '__main__':
    testcase = [[1,0,0],[0,0,0]]
    ans = Solution().shortestPath(testcase)
    print(ans)
1 Answers

bfs does not return a triple from all possible execution paths. If you finish the loop without finding a solution, then you drop out the bottom and return None. This makes your unpacking assignment fail.

Please see debug for your future use; we expect you to do the initial problem diagnosis, not merely dump an untracked program on us.

Related