You are asked to cut off all the trees in a forest for a golf event. The forest is represented as an m x n
matrix. In this matrix:
0
means the cell cannot be walked through.1
represents an empty cell that can be walked through.- A number greater than
1
represents a tree in a cell that can be walked through, and this number is the tree's height.
In one step, you can walk in any of the four directions: north, east, south, and west. If you are standing in a cell with a tree, you can choose whether to cut it off.
You must cut off the trees in order from shortest to tallest. When you cut off a tree, the value at its cell becomes 1
(an empty cell).
Starting from the point (0, 0)
, return the minimum steps you need to walk to cut off all the trees. If you cannot cut off all the trees, return -1
.
You are guaranteed that no two trees have the same height, and there is at least one tree needs to be cut off.
Example 1:
Input: forest = [[1,2,3],[0,0,4],[7,6,5]] Output: 6 Explanation: Following the path above allows you to cut off the trees from shortest to tallest in 6 steps.
Example 2:
Input: forest = [[1,2,3],[0,0,0],[7,6,5]] Output: -1 Explanation: The trees in the bottom row cannot be accessed as the middle row is blocked.
Example 3:
Input: forest = [[2,3,4],[0,0,5],[8,7,6]] Output: 6 Explanation: You can follow the same path as Example 1 to cut off all the trees. Note that you can cut off the first tree at (0, 0) before making any steps.
Constraints:
m == forest.length
n == forest[i].length
1 <= m, n <= 50
0 <= forest[i][j] <= 109
Related Topics:
Array, Breadth-First Search, Heap (Priority Queue), Matrix
// OJ: https://leetcode.com/problems/cut-off-trees-for-golf-event/
// Author: github.com/lzl124631x
// Time: O((MN)^2)
// Space: O(MN)
class Solution {
public:
int cutOffTree(vector<vector<int>>& A) {
int M = A.size(), N = A[0].size();
vector<array<int, 2>> v;
for (int i = 0; i < M; ++i) {
for (int j = 0; j < N; ++j) {
if (A[i][j] > 1) v.push_back({i, j});
}
}
sort(begin(v), end(v), [&](auto &a, auto &b) { return A[a[0]][a[1]] < A[b[0]][b[1]]; });
int seen[51][51] = {}, ans = 0, dirs[4][2] = {{0,1},{0,-1},{1,0},{-1,0}};
auto bfs = [&](array<int, 2> &from, array<int, 2> &to) {
queue<array<int, 2>> q{{from}};
memset(seen, 0, sizeof(seen));
int step = 0;
while (q.size()) {
int cnt = q.size();
while (cnt--) {
auto [x, y] = q.front();
q.pop();
if (x == to[0] && y == to[1]) return step;
for (auto &[dx, dy] : dirs) {
int a = x + dx, b = y + dy;
if (a < 0 || a >= M || b < 0 || b >= N || A[a][b] == 0 || seen[a][b]) continue;
seen[a][b] = 1;
q.push({a, b});
}
}
++step;
}
return -1;
};
array<int, 2> prev = {0,0};
for (auto &p : v) {
int len = bfs(prev, p);
if (len == -1) return -1;
ans += len;
prev = p;
}
return ans;
}
};