LeetCode 542 01矩阵

题目:

给定一个由 0 和 1 组成的矩阵,找出每一个元素到最近的 0 的距离。
两个相邻元素间的距离为 1 。web

示例 1: 
输入:
0 0 0
0 1 0
0 0 0

输出:
0 0 0
0 1 0
0 0 0

示例 2: 
输入:
0 0 0
0 1 0
1 1 1

输出:
0 0 0
0 1 0
1 2 1

注意:
给定矩阵的元素个数不超过 10000。
给定矩阵中至少有一个元素是 0。
矩阵中的元素只在四个方向上相邻: 上、下、左、右。数组

连接:https://leetcode-cn.com/problems/01-matrix数据结构

分析

这里我主要是使用了DFS+剪枝,最好的方法应该是DP(不过我不太会,卑微)。
由于矩阵的元素不超过10000,因此多是110000或者100001大小,若是直接开个数组(10000*10000)去存状态,会爆内存,因此这里咱们使用map这一数据结构去存状态,判断该点有没有访问过。在主函数中,咱们遍历矩阵中的每一个值,若是其值不为0,且相邻不为0(第一个剪枝),则就须要修改,咱们清空map数组,而后进行dfs操做,若是如今点的距离已经大于该点存的值,则就直接退出(第二个剪枝),若是到了0且距离比以前存的更小,则就更新,最后就获得了答案。svg

code:

struct Points
{
    int x;
    int y;
    Points(int a, int b)
    {
        x = a;
        y = b;
    }
};

class Solution {
    int row;
    int col;
	// 方向数组
    int dirs[4][2] = {{0,1},{1,0},{0,-1},{-1,0}};
    map<int, map<int, bool> > mp;
    // 判断有没有超出范围
    bool f(int i, int j)
    {
        if(i < 0 || j < 0 || i >= row || j >= col)
            return false;
        return true;
    }
    
    // 用来剪枝的函数
    bool g(int x, int y, vector<vector<int>>& matrix)
    {
        for(int i = 0; i < 4; i++)
        {
            int xt = x + dirs[i][0];
            int yt = y + dirs[i][1];
            if(f(xt, yt) && matrix[xt][yt] == 0)
                return false;
        }
        return true;
    }
    
    
    void dfs(vector<vector<int>>& matrix, int i, int j, int targetx, int targety)
    {
        int dis = abs(targetx-i) + abs(targety-j);
        if(dis >= matrix[targetx][targety])
            return ;
        else if(matrix[i][j] == 0)
        {
            if(matrix[targetx][targety] > dis)
                matrix[targetx][targety] = dis;
            return ;
        }
        else
        {
            for(int k = 0; k < 4; k++)
            {
                int xt = i + dirs[k][0];
                int yt = j + dirs[k][1];
                if(f(xt, yt) && !mp[xt][yt])
                {
                    mp[xt][yt] = true;
                    // cout << xt << '-' << yt << endl;
                    dfs(matrix, xt, yt, targetx, targety);    
                }
            }
        }
    }
    
public:
    vector<vector<int>> updateMatrix(vector<vector<int>>& matrix) {
        row = matrix.size();
        if(row == 0)
            return matrix;
        col = matrix[0].size();
        for(int i = 0; i < row; i++)
        {
            for(int j = 0; j < col; j++)
            {
                if(matrix[i][j] != 0 && g(i, j, matrix))
                {
                    mp.erase(mp.begin(), mp.end());
                    matrix[i][j] = row+col;
                    mp[i][j] = 1;
                    dfs(matrix, i, j, i, j);
                }
            }
        }
        return matrix;
    }
};