01 Matrix

Given a matrix consists of 0 and 1, find the distance of the nearest 0 for each cell.

The distance between two adjacent cells is 1.

 

Example 1:

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

Output:
[[0,0,0],
 [0,1,0],
 [0,0,0]]

Example 2:

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

Output:
[[0,0,0],
 [0,1,0],
 [1,2,1]]

 

Note:

  1. The number of elements of the given matrix will not exceed 10,000.
  2. There are at least one 0 in the given matrix.
  3. The cells are adjacent in only four directions: up, down, left and right.

 

 

以下包括三种解法:

1. 从1去找最近0的距离

2. 两次扫描,分别从左-上和从右-下,保证了四个方向都是最近的。

3.从0去更新距离

 

Code:

    vector<vector<int>> updateMatrix(vector<vector<int>>& matrix) { //****** Solution 1; Low efficent; from 1 to find the nearest 0
        vector<vector<int>> distance = matrix;
        for(int i = 0; i < matrix.size(); i++) {
            for(int j = 0; j < matrix[0].size(); j++) {
                if(matrix[i][j] == 0) distance[i][j] = 0;
                else {
                    distance[i][j] = BFS(matrix, i, j);
                }
            }
        }
        return distance;
    }
        
    int BFS(vector<vector<int>>& matrix, int r, int c) {
        int step;
        set<pair<int, int>> visited;
        queue<pair<int, int>> q;
        q.push(make_pair(r,c));
        visited.insert(make_pair(r,c));
        for(step = 0;  ; step++) {
            for(int size = q.size(); size > 0; size--) {
                auto front = q.front(); q.pop();
                visited.insert(front);
                if(matrix[front.first][front.second] == 0) {
                    return step;
                }
                else { //four directions
                    vector<vector<int>> dirs{{0, 1}, {0, -1}, {-1, 0}, {1, 0}};
                    for(auto d : dirs) {
                        int r = front.first + d[0], c = front.second + d[1];
                        if(r < 0 or r >= matrix.size() or c < 0 or c >= matrix[0].size() or visited.find({r,c}) != visited.end()) {
                            continue;
                        }
                        q.push({r, c});
                    }
                }
            }
        }
        return step;
    }
 vector<vector<int>> updateMatrix(vector<vector<int>>& matrix) { // *******  Solution 2; two sweeps:up-left and bottom-right
        int h = matrix.size(), w = matrix[0].size();
        vector<vector<int>> res(h, vector<int>(w, INT_MAX-1));
        for(int i = 0; i < h; i++) {
            for(int j = 0; j < w; j++) {
                if(matrix[i][j] == 0) 
                    res[i][j] = 0;
                else {
                    if(i > 0) res[i][j] = min(res[i][j], res[i-1][j]+1);
                    if(j > 0) res[i][j] = min(res[i][j], res[i][j-1]+1);
                }
            }
        }
        
        for(int i = h - 1; i >= 0; i--) {
            for(int j = w - 1; j >= 0; j--) {
                if(res[i][j] == 0 or res[i][j] == 1)
                    continue;
                if(i < h - 1) res[i][j] = min(res[i][j], res[i+1][j]+1);
                if(j < w - 1) res[i][j] = min(res[i][j], res[i][j+1]+1);
            }
        }
        
        return res;
    }
vector<vector<int>> updateMatrix(vector<vector<int>>& matrix) { //******   Solution 3; Low; from 0 to update distance
        int h = matrix.size(), w = matrix[0].size();
        vector<vector<int>> distance(h, vector<int>(w, INT_MAX-1));
        queue<pair<int, int>> q;
        for(int i = 0; i < h; i++) {
            for(int j = 0; j < w; j++) {
                if(matrix[i][j] == 0) {
                    distance[i][j] = 0;
                    q.push({i, j});  // source
                }
            }
        }
        
        vector<vector<int>> dirs{{-1, 0}, {1, 0}, {0, -1}, {0, 1}}; // four directions
        while(!q.empty()) {
            auto f = q.front(); q.pop();
            for(auto d : dirs) {
                int r = f.first + d[0], c = f.second + d[1]; // around
                if(r < 0 or r >= h or c < 0 or c >= w or distance[r][c] <= distance[f.first][f.second] + 1)
                    continue;
                distance[r][c] = distance[f.first][f.second] + 1;
                q.push({r, c});
            }
        }
        
        return distance;
    }

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值