542. 01 Matrix -- Medium

Description

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

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

Analyze

Firstly, we will notice that the given function name is updateMatrix while not findClosest or something, which means I don’t need new space to solve the problem, just updating instead.
I didn’t use DFS although I search the problem by this tag, but I found many good particularities in this problem:

  • Traverse and update the matrix, and we can ignore 0.
  • We already knew the updated above value and left value because of the sequence of traverse.
  • If there exist less steps than above or left value + 1, than the corresponding nearer zero must be in lower right corner.

That’s all of the main points.

Detail

How to find the nearest zero in the lower right corner?
I use a variable called step, the elements we can reach from matrix[i][j] in step are matrix[i + k][j + step - k](k from 0 to step). So we can have them in a loop.
Another trouble is how to deal with ArrayIndexOutOfBounds.

code

vector<vector<int>> updateMatrix(vector<vector<int>>& matrix) {
    int row = matrix.size();
    int col = matrix[0].size();
    for(int i = 0; i < row; ++i) {
        for(int j = 0; j < col; ++j) {
            if(matrix[i][j] != 0) {
                int above = (i - 1 >= 0) ? (matrix[i - 1][j] + 1) : 10000;
                int left = (j - 1 >= 0) ? (matrix[i][j - 1] + 1) : 10000;
                int less = above > left ? left : above;
                int step = 0;
                int step_max = row - 1 - i + col - 1 - j;
                if(less < step_max) step_max = less - 1;
                bool found = false;
                while(step < step_max && !found) {
                    ++step;
                    for(int k = 0; k <= step; k++) {
                        if(i + k >= row || j + step - k >= col) continue;
                        if(matrix[i + k][j + step - k] == 0) {
                            found = true;
                            break;
                        }
                    }
                }
                matrix[i][j] = (found && less > step) ? step : less;
            } 
        }
    }
    return matrix;
}

TLE

The last input is [[0, 1], [0, 1], [0, 1]……[0, 1]] when I got TLE. This is because I spent a lot of time in searching those out-of-bound matrix[i + k][j + step - k]. Then I found two ways to improve my algorithm.
One of them is setting a step_max as I did in code. Step_max is min{above, left}, so we can avoid serarching too far if the solution in lower right coner is worse. And I got AC after I made this improvement.
Another one is a trick. It’s not hard to see that, once we have a “shortest path”, then the value of sub-matrix, whose top left corner is the source of the shortest path, and the lower right corner is the destination of the shortest path, can be settled. But since I have got AC, I did’t perform that.

//this could be done in one round
1 1 1 1       6 5 4 3
1 1 1 1       5 4 3 2
1 1 1 1  -->  4 3 2 1
1 1 1 0       3 2 1 0

Summary

BFS is an obvious solution at very first. However, I blame my poor Data Struct learning that I do not like graph algorithm. So I didn’t choose BFS and found a more interesting solution.
As graph algorithm is my weakness, I also checked others’ code and I will practice it in the next puzzle.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值