• + 0 comments

    We don't necessarily need to build a graph. We can use a queue directly. Here is my Python solution:

    from collections import deque
    def minimumMoves(grid, startX, startY, goalX, goalY):
        # Note: 
        # X means vertical direction in problem description's diagram
        # Y means horizontal direction in problem descritions's diagram
        # This is different with our habit. 
        # So I don't use the word left, right, up, or down in my code to avoid misleading names
        
        len_X = len(grid)
        len_Y = len(grid[0])
        visited = []
        for i in range(len_X):
            visited.append([False]*len_Y)
        
        queue = deque()
        # In the queue, each element is a tuple
        # Each tuple has 3 elements: x, y, and the number of moves from starting point to this location
        queue.append((startX, startY, 0))
        visited[startX][startY] = True
        while queue:
            cur_x, cur_y, cur_d = queue.popleft()
            
            if cur_x == goalX and cur_y == goalY:
                return cur_d
            
            #Add all potential moves toward smaller X
            for x in range(cur_x)[::-1]:
                if grid[x][cur_y] == '.' and not visited[x][cur_y]:
                    queue.append((x,cur_y,cur_d+1))
                    visited[x][cur_y] = True
                elif grid[x][cur_y] == 'X':
                    break
                    
            #Add all potential moves toward bigger X
            for x in range(cur_x,len_X):
                if grid[x][cur_y] == '.' and not visited[x][cur_y]:
                    queue.append((x,cur_y,cur_d+1))
                    visited[x][cur_y] = True
                elif grid[x][cur_y] == 'X':
                    break
                    
            #Add all potential moves toward smaller Y
            for y in range(cur_y)[::-1]:
                if grid[cur_x][y] == '.' and not visited[cur_x][y]:
                    queue.append((cur_x,y,cur_d+1))
                    visited[cur_x][y] = True
                elif grid[cur_x][y] == 'X':
                    break
                    
            #Add all potential moves toward bigger Y
            for y in range(cur_y,len_Y):
                if grid[cur_x][y] == '.' and not visited[cur_x][y]:
                    queue.append((cur_x,y,cur_d+1))
                    visited[cur_x][y] = True
                elif grid[cur_x][y] == 'X':
                    break
        return -1   # The flag when the goal is not reachable