本文共 5177 字,大约阅读时间需要 17 分钟。
0 表示障碍,无法触碰到.
1 表示可以行走的地面. 比1大的数 表示一颗允许走过的树的高度. 你被要求按照树的高度从低向高砍掉所有的树,每砍过一颗树,树的高度变为1。你将从(0,0)点开始工作,你应该返回你砍完所有树需要走的最小步数。 如果你无法砍完所有的树,返回 -1 。
可以保证的是,没有两棵树的高度是相同的,并且至少有一颗树需要你砍。
示例 1:
输入:
[ [1,2,3], [0,0,4], [7,6,5] ] 输出: 6示例 2:
输入:
[ [1,2,3], [0,0,0], [7,6,5] ] 输出: -1示例 3:
输入:
[ [2,3,4], [0,0,5], [8,7,6] ] 输出: 6解释: (0,0) 位置的树,你可以直接砍去,不用算步数
提示: 矩阵大小不会超过 50x50 。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/cut-off-trees-for-golf-event 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。package com.bean.leetcode;import java.util.Comparator;import java.util.LinkedList;import java.util.List;import java.util.PriorityQueue;import java.util.Queue;public class Solution675_2 { int row, col; public int cutOffTree(List
> forest) { // 先遍历矩阵,找到所有需要砍的树的位置,保存在最小堆中,按树高排序 // 建堆 PriorityQueue minHeap = new PriorityQueue<>(new Comparator () { @Override public int compare(int[] o1, int[] o2) { return forest.get(o1[0]).get(o1[1]) - forest.get(o2[0]).get(o2[1]); } }); // 找到所有需要砍的树的位置 if (forest == null) return 0; row = forest.size(); if (row == 0) return 0; col = forest.get(0).size(); for (int i = 0; i < row; i++) { for (int j = 0; j < col; j++) { if (forest.get(i).get(j) > 1) minHeap.add(new int[] { i, j }); } } // 开始从小砍到大 int count = 0; int[] begin = new int[] { 0, 0 }; while (!minHeap.isEmpty()) { int[] end = minHeap.poll(); int temp = cutOffTree(forest, begin, end, new int[row][col]); if (temp == -1) return -1; count += temp; begin = end; } return count; } /** 找到 begin -> end 的最短的路径,BFS * @param forest >= 0 表示可以行走, 0 表示障碍 * @param begin 起始位置 * @param end 目标位置 * @return 最短的路径长度,原地 begin = end 为 0 */ public int cutOffTree(List
> forest, int[] begin, int[] end, int[][] visited) { if(end[0] == begin[0] && end[1] == begin[1]) return 0; // BFS Queue queue = new LinkedList<>(); queue.add(begin); int depth = 0; while (!queue.isEmpty()) { depth++; for (int i = 0, len = queue.size(); i < len; i++) { int[] pos = queue.poll(); // 再走一步 if(pos[0] > 0 && visited[pos[0] - 1][pos[1]] == 0) { if(end[0] == pos[0] - 1 && end[1] == pos[1]) return depth; if(forest.get(pos[0] - 1).get(pos[1]) != 0){ queue.add(new int[]{pos[0] - 1, pos[1]}); visited[pos[0] - 1][pos[1]] = 1; } } if(pos[1] > 0 && visited[pos[0]][pos[1] - 1] == 0) { if(end[0] == pos[0] && end[1] == pos[1] - 1) return depth; if(forest.get(pos[0]).get(pos[1] - 1) != 0){ queue.add(new int[]{pos[0], pos[1] - 1}); visited[pos[0]][pos[1] - 1] = 1; } } if(pos[0] + 1 < row && visited[pos[0] + 1][pos[1]] == 0) { if(end[0] == pos[0] + 1 && end[1] == pos[1]) return depth; if(forest.get(pos[0] + 1).get(pos[1]) != 0){ queue.add(new int[]{pos[0] + 1, pos[1]}); visited[pos[0] + 1][pos[1]] = 1; } } if(pos[1] + 1 < col && visited[pos[0]][pos[1] + 1] == 0) { if(end[0] == pos[0] && end[1] == pos[1] + 1) return depth; if(forest.get(pos[0]).get(pos[1] + 1) != 0){ queue.add(new int[]{pos[0], pos[1] + 1}); visited[pos[0]][pos[1] + 1] = 1; } } } } // 无法走到下一棵需要砍的树 return -1; }}
package com.bean.leetcode;import java.util.ArrayList;import java.util.Collections;import java.util.Comparator;import java.util.LinkedList;import java.util.List;import java.util.Queue;public class Solution675 { int[][] dir = { { -1, 0 }, { 1, 0 }, { 0, -1 }, { 0, 1 } }; public int cutOffTree(List
> forest) { if (forest == null || forest.size() == 0) return -1; int m = forest.size(), n = forest.get(0).size(), res = 0; // first step: sort the tree position based on its height List heights = new ArrayList<>(); for (int i = 0; i < m; i++) { for (int j = 0; j < n; j++) { if (forest.get(i).get(j) > 1) heights.add(new int[] { forest.get(i).get(j), i, j }); } } Collections.sort(heights, new Comparator () { public int compare(int[] arr1, int[] arr2) { return Integer.compare(arr1[0], arr2[0]); } }); // second step: accumulate the shortest steps between each two adajacent points // in heights[]. int start_x = 0, start_y = 0; for (int i = 0; i < heights.size(); i++) { int cnt_steps = BFS(forest, m, n, start_x, start_y, heights.get(i)[1], heights.get(i)[2]); if (cnt_steps == -1) return -1; res += cnt_steps; start_x = heights.get(i)[1]; start_y = heights.get(i)[2]; } return res; } public int BFS(List
> forest, int m, int n, int start_x, int start_y, int des_x, int des_y) { if (start_x == des_x && start_y == des_y) return 0; int steps = 0; Queue q = new LinkedList<>(); q.add(new int[] { start_x, start_y }); int[][] visited = new int[m][n]; visited[start_x][start_y] = 1; while (!q.isEmpty()) { int qsize = q.size(); steps++; while (qsize-- > 0) { int[] cur = q.poll(); int cur_x = cur[0], cur_y = cur[1]; for (int k = 0; k < 4; k++) { int x = cur_x + dir[k][0], y = cur_y + dir[k][1]; if (x >= 0 && x < m && y >= 0 && y < n && forest.get(x).get(y) > 0 && visited[x][y] == 0) { if (x == des_x && y == des_y) return steps; visited[x][y] = 1; q.add(new int[] { x, y }); } } } } return -1; }}
以上代码提交,都Accepted~