博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
LeetCode刷题:675. 为高尔夫比赛砍树(JAVA代码详解)
阅读量:4040 次
发布时间:2019-05-24

本文共 5177 字,大约阅读时间需要 17 分钟。

675. 为高尔夫比赛砍树(JAVA代码详解)

你被请来给一个要举办高尔夫比赛的树林砍树. 树林由一个非负的二维数组表示, 在这个数组中:

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~

 

你可能感兴趣的文章
Selenium-Css Selector使用方法
查看>>
Linux常用统计命令之wc
查看>>
测试必会之 Linux 三剑客之 sed
查看>>
Socket请求XML客户端程序
查看>>
Java中数字转大写货币(支持到千亿)
查看>>
Java.nio
查看>>
函数模版类模版和偏特化泛化的总结
查看>>
VMware Workstation Pro虚拟机不可用解决方法
查看>>
最简单的使用redis自带程序实现c程序远程访问redis服务
查看>>
redis学习总结-- 内部数据 字符串 链表 字典 跳跃表
查看>>
iOS 对象序列化与反序列化
查看>>
iOS 序列化与反序列化(runtime) 01
查看>>
iOS AFN 3.0版本前后区别 01
查看>>
iOS ASI和AFN有什么区别
查看>>
iOS QQ侧滑菜单(高仿)
查看>>
iOS 扫一扫功能开发
查看>>
iOS app之间的跳转以及传参数
查看>>
iOS __block和__weak的区别
查看>>
Android(三)数据存储之XML解析技术
查看>>
Spring JTA应用之JOTM配置
查看>>