阿里笔试第二题(BFS,java,python)

1. 问题

阿里笔试第二题
给你一个迷宫,包括一个起点‘S’和一个终点‘E’,‘#’表示障碍,不可到达的位置,‘.'表示可以到达的位置,另外你可以跳跃,跳跃的规则是从一个点跳到该点在迷踪的中心对称的那个点上,最多跳跃5次,求从起点到达终点的最短路径长度。

2. 解决方法

BFS思路,就是遍历四个方向加跳跃(记住跳跃的次数),遍历过的加入到visited;如果不是障碍加到候选队列;直到找到终点或者遍历完。

import java.util.*;

class Migong{
    static class Node{
        int row;
        int col;
        int jumpCount;
        int pathLen;
        Node (int row, int col, int jumpCount, int pathLen){
            this.row = row;
            this.col = col;
            this.jumpCount = jumpCount;
            this.pathLen = pathLen;
        }
    }
    public static int shortestPath(char[][] grid, int k){
        int m = grid.length;
        int n = grid[0].length;
        LinkedList<Node> queue = new LinkedList<>();
        // get start
        boolean found = false;
        int startX = 0;
        int startY = 0;
    	for(int i=0;i<m;i++) {
    		for(int j=0;j<n;j++) {
    			if(grid[i][j] == 'S') {
    				startX = i;
    				startY = j;
    				found = true;
    				break;
    			}
    		}
    		if(found) break;
    	}
    		
        Node rootNode = new Node(startX,startY,0,0);
        queue.add(rootNode);
        Node[][] visited = new Node[m][n];
        visited[0][0] = rootNode;
        
        int dx[] = new int[]{-1,1,0,0};
        int dy[] = new int[]{0,0,1,-1};
        
        while(!queue.isEmpty()){
            int count = queue.size();
            while(count-->0){
                Node tmp = queue.poll();
                int row = tmp.row;
                int col = tmp.col;
                int jumpCount = tmp.jumpCount;
                int pathLen = tmp.pathLen;
                if(grid[row][col] == 'E'){
                    return pathLen;
                }
                //four directions
                for(int i = 0;i < 4;i++){
                    int newRow = row + dx[i];
                    int newCol = col + dy[i];
                    if(newRow<0 || newRow>=m || newCol<0 || newCol>=n ){
                        continue;
                    }
                    if(jumpCount > k){
                        continue;
                    }
                    boolean addNode = false;
                    int newPathLen = -1;
                    if(grid[row][col] != '#') {
                    	newPathLen = pathLen+1;
                    	addNode = true;
                    }
                    Node newNode = new Node(newRow, newCol, jumpCount,newPathLen);
                    if(addNode) queue.add(newNode);
                    if(visited[newRow][newCol] == null){
                        visited[newRow][newCol] = newNode;
                    }
                }
                // jump
                int newRow = m - 1-row;
                int newCol = n - 1-col;
                if(newRow<0 || newRow>=m || newCol<0 || newCol>=n || jumpCount>5){
                    ;
                }
                else {
                    boolean addNode = false;
                    int newPathLen = -1;
                    if(grid[row][col] != '#') {
                    	newPathLen = pathLen+1;
                    	addNode = true;
                    }
                    Node newNode = new Node(newRow, newCol, jumpCount+1,newPathLen);
                    if(addNode) queue.add(newNode);
                    if(visited[newRow][newCol] == null|| jumpCount+1<visited[newRow][newCol].jumpCount){
                        visited[newRow][newCol] = newNode;
                    }
                }
            }

        }
        return -1;
    }

    public static void main(String[] args){
    	char[][] grid = {{'#', 'S', '.', '.','.'},
						{'E', '#', '#', '.','.'},
						{'#', '#', '#', '.','.'},
						{'#', '#', '#', '.','.'}};
		int result = shortestPath(grid,5);                   
		System.out.println(result);
    }
}

python 代码:

import collections
from typing import List
class Solution:
    def shortestPath(self, grid: List[List[int]], k: int) -> int:
        m, n = len(grid), len(grid[0])
        if m == 1 and n == 1:
            return 0
        # start point
        found = False
        sx = 0
        sy = 0
        for i in range(m):
            for j in range(n):
                if grid[i][j] == 'S':
                    sx = i
                    sy = j
                    found = True
                    break
            if found:
                break
        visited = set([(sx, sy, k)])
        q = collections.deque([(sx, sy, k)])
        step = 0
        while len(q) > 0:
            step += 1
            cnt = len(q)
            for _ in range(cnt):
                x, y, rest = q.popleft()
                for dx, dy in [(-1, 0), (1, 0), (0, -1), (0, 1)]:
                    nx, ny = x + dx, y + dy
                    if 0 <= nx < m and 0 <= ny < n:
                            if grid[nx][ny] == 'E':
                                return step
                            if (nx, ny, rest) not in visited:
                                if grid[nx][ny] != '#':
                                    q.append((nx, ny, rest))
                                visited.add((nx, ny, rest))
                # jump
                if rest>0:
                    nx, ny = m-1-x, n-1-y
                    if grid[nx][ny] == 'E':
                        return step
                    if (nx, ny, rest) not in visited:
                        if grid[nx][ny] != '#':
                            q.append((nx, ny, rest-1))
                        visited.add((nx, ny, rest-1))
        return -1

solution = Solution()
grid =  \
[['#', 'S', '.', '.'],\
['E', '#', '#', '.'],\
['#', '#', '#', '.'],\
['#', '#', '#', '.']]
k = 5
print(solution.shortestPath(grid,k))

参考:

  1. 阿里3.23日笔试第二题交流;
发布了510 篇原创文章 · 获赞 152 · 访问量 77万+

猜你喜欢

转载自blog.csdn.net/rosefun96/article/details/105061017
今日推荐