LintCode 1888: Shortest Path in Matrix (BFS好题)

1888. Shortest Path in Matrix

 

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.

 

Example

input:[[1,0,1],[0,0,0],[1,0,0]]

output:[[1,4,1],[2,2,2],[1,4,2]]

 

Notice

0<m,n<1000

解法1:BFS

思路跟Zombie那题很像,都是从destinations的几个节点开始进queue。

注意:

1) 因为BFS是从destination往empty的节点找,所以上下左右的权值要反过来。

2) 可以直接把权值(2,3,4,5)写到grid[][]里面去。

3) round[i][j]表示grid[i][j]最早是在第几轮更新的。

4) 因为同一轮中,某个empty节点可能会被多个destination节点扩展到,所以要根据权值决定要不要覆盖。

                            if (dirMarks[j] < grid[newX][newY]) { 
                                grid[newX][newY] = dirMarks[j];
                            }


struct Node {
    int x;
    int y;
    Node(int _x = 0, int _y = 0) : x(_x), y(_y) {}
};

class Solution {
public:
    /**
     * @param grid: the input matrix
     * @return: the new matrix
     */
    vector<vector<int>> shortestPath(vector<vector<int>> &grid) {
        int m = grid.size();
        if (m == 0) return {};
        int n = grid[0].size();
        vector<vector<int>> rounds(m, vector<int>(n));
        vector<int> dirMarks = {2, 3, 4, 5}; //DOWN, UP, RIGHT, LEFT
        
        queue<Node> q;
        for (int i = 0; i < m; ++i) {
            for (int j = 0; j < n; ++j) {
                if (grid[i][j] == 1) q.push(Node(i, j));
            }
        }
        
        vector<int> dx = {1, -1, 0, 0};   //DOWN, UP, RIGHT, LEFT
        vector<int> dy = {0, 0, 1, -1};
        int round = 0;
        while(!q.empty()) {
            int qSize = q.size();
            round++;
            for (int i = 0; i < qSize; ++i) {
                Node frontNode = q.front();
                q.pop();
                for (int j = 0; j < 4; ++j) {
                    int newX = frontNode.x + dx[j];
                    int newY = frontNode.y + dy[j];
                    if (newX >= 0 && newX < m && newY >= 0 && newY < n) {
                        if (grid[newX][newY] == 0) {
                            q.push(Node(newX, newY));
                            rounds[newX][newY] = round;
                            
                            grid[newX][newY] = dirMarks[j];
                            
                        } else if ((grid[newX][newY] >= 2) && (rounds[newX][newY] == round)) {
                            
                            if (dirMarks[j] < grid[newX][newY]) { 
                                grid[newX][newY] = dirMarks[j];
                            }
                        }
                    } 
                }
                
            }
        }
        return grid;
    }
};

也可以直接用pair<int,int>来表示Node。

class Solution {
public:
    /**
     * @param grid: the input matrix
     * @return: the new matrix
     */
    vector<vector<int>> shortestPath(vector<vector<int>> &grid) {
        int m = grid.size();
        if (m == 0) return {};
        int n = grid[0].size();
        vector<vector<int>> rounds(m, vector<int>(n));
        vector<int> dirMarks = {2, 3, 4, 5}; //DOWN, UP, RIGHT, LEFT
        
        queue<pair<int, int>> q;
        for (int i = 0; i < m; ++i) {
            for (int j = 0; j < n; ++j) {
                if (grid[i][j] == 1) q.push({i, j});
            }
        }
        
        vector<int> dx = {1, -1, 0, 0};   //DOWN, UP, RIGHT, LEFT
        vector<int> dy = {0, 0, 1, -1};
        int round = 0;
        while(!q.empty()) {
            int qSize = q.size();
            round++;
            for (int i = 0; i < qSize; ++i) {
                pair<int, int> frontNode = q.front();
                q.pop();
                for (int j = 0; j < 4; ++j) {
                    int newX = frontNode.first + dx[j];
                    int newY = frontNode.second + dy[j];
                    if (newX >= 0 && newX < m && newY >= 0 && newY < n) {
                        if (grid[newX][newY] == 0) {
                            q.push({newX, newY});
                            rounds[newX][newY] = round;
                            grid[newX][newY] = dirMarks[j];
                        } else if ((grid[newX][newY] >= 2) && (rounds[newX][newY] == round)) {
                            if (dirMarks[j] < grid[newX][newY]) { grid[newX][newY] = dirMarks[j];
                            }
                        }
                    } 
                }
            }
        }
        return grid;
    }
};

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值