LeetCode - 002 - 542. 01 Matrix

292 阅读3分钟

Date: 20200324

542. 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.

基本信息

Difficulty: Medium

Related Topics: Depth-first Search,Breadth-first Search

v0.1.0

不在一条直线上的也算,实际是算曼哈顿距离最短的0在哪里。一开始我以为只是在同一行或者同一列上。不过看结果发现有点规律。

可以从(0,0)(m,n),从上往下,从左往右过一遍,再从(m,n)(0,0),从下往上,从右往左过一遍。

matrix[i][j]==0时,answer[i][j]==0。不为0时,再进行判断。 从上往下的时候,取answer[i-1][j]answer[i][j-1]的中较小的值,加上1赋值给answer[i][j]。如果matrix[0][0]==0没那么计算很简单,如果matrix[0][0]==1怎么办呢?如果保持1的值,会对之后的遍历结果造成困扰,所以可以先赋值为-1,代表这个格子还没计算。

从下往上和上面描述的过程类似,就是计算变成answer[i][j]answer[i+1][j]+1answer[i][j+1]+1之间最小值。

当格子在最边上的行和列时,根据位置分情况讨论。

#include <iostream> 
#include <algorithm>
#include <limits>
using namespace std;

class Solution {
public:
    vector<vector<int>> updateMatrix(vector<vector<int>>& matrix) {
        vector<vector<int>> ans = matrix;
        
        for (int i = 0; i < ans.size(); i++) {
            for (int j = 0; j < ans[0].size(); j++) {
                if (ans[i][j] != 0) {
                    if (i == 0 && j != 0) {
                        if (ans[i][j-1] != -1) {
                            ans[i][j] = ans[i][j-1] + 1;
                        } else {
                            ans[i][j] = -1;
                        }
                    } else if (i != 0 && j == 0) {
                        if (ans[i-1][j] != -1) {
                            ans[i][j] = ans[i-1][j] + 1;
                        }else {
                            ans[i][j] = -1;
                        }
                        
                    } else if (i == 0 && j == 0) {
                        ans[i][j] = -1;
                    } else {
                        if (ans[i][j-1] == -1 && ans[i-1][j] != -1) {
                            ans[i][j] = ans[i-1][j] + 1;
                        } else if (ans[i][j-1] != -1 && ans[i-1][j] == -1) {
                            ans[i][j] = ans[i][j-1] + 1;
                        } else if (ans[i][j-1] == -1 && ans[i-1][j] == -1) {
                            ans[i][j] = -1;
                        } else {
                            ans[i][j] = min(ans[i][j-1], ans[i-1][j]) + 1; 
                        }
                    
                    }
                    
                }
            }
        }
        
        for (int i = ans.size()-1; i >= 0; i--) {
            for (int j = ans[0].size() - 1; j >= 0; j--) {
                if (ans[i][j] != 0) {
                    if (i == ans.size()-1 && j != ans[0].size() - 1) {
                        if (ans[i][j] != -1) {
                           ans[i][j] = min(ans[i][j], ans[i][j+1]+1); 
                        } else {
                            ans[i][j] = ans[i][j+1]+1;
                        }
                        
                    } else if (i != ans.size()-1 && j == ans[0].size() - 1) {
                        if (ans[i][j] != -1) {
                            ans[i][j] = min(ans[i][j], ans[i+1][j]+1);
                        }else {
                            ans[i][j] = ans[i+1][j]+1;
                        }
                        
                    } else if (i == ans.size()-1 && j == ans[0].size() - 1) {
                        ans[i][j] = ans[i][j];
                    } else {
                        if (i==0 && j == 0) {
                            ans[i][j] = min(ans[i][j+1], ans[i+1][j])+1;
                        } else {
                            int m_int = min(ans[i][j+1], ans[i+1][j])+1;
                            if (ans[i][j] != -1) {
                                ans[i][j] = min(m_int, ans[i][j]);
                            } else {
                                ans[i][j] = m_int;
                            }
                            
                            
                        }
                        
                    }
                    
                }
            }
        }
        
        return ans;
        
    }
    

};

submission

Runtime: 208 ms, faster than 39.29% of C++ online submissions for 01 Matrix. Memory Usage: 18.2 MB, less than 100.00% of C++ online submissions for 01 Matrix. Next challenges:

反思

这个判断+1-1的这么多,写着写着我都晕了。应该有更好的方式。标签里有BFS,有DFS,但是如果用搜索的话效率应该比较低?感觉会进行很多重复的计算。

18-line C++ DP Solution, O(n), Easy to Understand 看这个写法我意识到从上往下的时候可以检查上下左右,标记出无法直接计算距离的,然后从下往上遍历的时候只修改这些还没计算的格子。

从上往下时标记出来的从下往上时可以跳过不看。