[LeetCode] Cut Off Trees for Golf Event 為高爾夫賽事砍樹


 

You are asked to cut off trees in a forest for a golf event. The forest is represented as a non-negative 2D map, in this map:

  1. 0 represents the obstacle can't be reached.
  2. 1 represents the ground can be walked through.
  3. The place with number bigger than 1 represents a tree can be walked through, and this positive number represents the tree's height.

 

You are asked to cut off all the trees in this forest in the order of tree's height - always cut off the tree with lowest height first. And after cutting, the original place has the tree will become a grass (value 1).

You will start from the point (0, 0) and you should output the minimum steps you need to walk to cut off all the trees. If you can't cut off all the trees, output -1 in that situation.

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: 
[
 [1,2,3],
 [0,0,4],
 [7,6,5]
]
Output: 6

 

Example 2:

Input: 
[
 [1,2,3],
 [0,0,0],
 [7,6,5]
]
Output: -1

 

Example 3:

Input: 
[
 [2,3,4],
 [0,0,5],
 [8,7,6]
]
Output: 6
Explanation: You started from the point (0,0) and you can cut off the tree in (0,0) directly without walking.

 

Hint: size of the given matrix will not exceed 50x50.

 

這道題讓我們砍掉所有高度大於1的樹,而且要求是按順序從低到高來砍,那么本質實際上還是要求任意兩點之間的最短距離啊。對於這種類似迷宮遍歷求最短路徑的題,BFS是不二之選啊。那么這道題就對高度相鄰的兩棵樹之間調用一個BFS,所以我們可以把BFS的內容放倒子函數helper中來使用。那么我們首先就要將所有的樹從低到高進行排序,我們遍歷原二位矩陣,將每棵樹的高度及其橫縱坐標取出來,組成一個三元組,然后放到vector中,之后用sort對數組進行排序,因為sort默認是以第一個數字排序,這也是為啥我們要把高度放在第一個位置。然后我們就遍歷我們的trees數組,我們的起始位置是(0,0),終點位置是從trees數組中取出的樹的位置,然后調用BFS的helper函數,這個BFS的子函數就是很基本的寫法,沒啥過多需要講解的地方,會返回最短路徑的值,如果無法到達目標點,就返回-1。所以我們先檢查,如果helper函數返回-1了,那么我們就直接返回-1,否則就將cnt加到結果res中。然后更新我們的起始點為當前樹的位置,然后循環取下一棵樹即可,參見代碼如下:

 

class Solution {
public:
    int cutOffTree(vector<vector<int>>& forest) {
        int m = forest.size(), n = forest[0].size(), res = 0, row = 0, col = 0;
        vector<vector<int>> trees;
        for (int i = 0; i < m; ++i) {
            for (int j = 0; j < n; ++j) {
                if (forest[i][j] > 1) trees.push_back({forest[i][j], i, j});
            }
        }
        sort(trees.begin(), trees.end());
        for (int i = 0; i < trees.size(); ++i) {
            int cnt = helper(forest, row, col, trees[i][1], trees[i][2]);
            if (cnt == -1) return -1;
            res += cnt;
            row = trees[i][1];
            col = trees[i][2];
        }
        return res;
    }
    int helper(vector<vector<int>>& forest, int row, int col, int treeRow, int treeCol) {
        if (row == treeRow && col == treeCol) return 0;
        int m = forest.size(), n = forest[0].size(), cnt = 0;
        queue<int> q{{row * n + col}};
        vector<vector<int>> visited(m, vector<int>(n));
        vector<int> dir{-1, 0, 1, 0, -1};
        while (!q.empty()) {
            ++cnt;
            for (int i = q.size(); i > 0; --i) {
                int r = q.front() / n, c = q.front() % n; q.pop();
                for (int k = 0; k < 4; ++k) {
                    int x = r + dir[k], y = c + dir[k + 1];
                    if (x < 0 || x >= m || y < 0 || y >= n || visited[x][y] == 1 || forest[x][y] == 0) continue;
                    if (x == treeRow && y == treeCol) return cnt;
                    visited[x][y] = 1;
                    q.push(x * n + y);
                }
            }
        }
        return -1;
    }
}; 

 

參考資料:

https://leetcode.com/problems/cut-off-trees-for-golf-event/

https://leetcode.com/problems/cut-off-trees-for-golf-event/discuss/107403/c-sort-bfs-with-explanation

https://leetcode.com/problems/cut-off-trees-for-golf-event/discuss/107404/java-solution-priorityqueue-bfs

 

LeetCode All in One 題目講解匯總(持續更新中...)


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM