【刷题】675. 为高尔夫比赛砍树

2024-02-05 12:40

本文主要是介绍【刷题】675. 为高尔夫比赛砍树,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

文章目录

  • 题目
  • 思路
  • 解题
    • python实现
    • golang实现
  • 复杂度
  • 总结


题目

leetCode链接:https://leetcode.cn/problems/cut-off-trees-for-golf-event/

  1. 为高尔夫比赛砍树

你被请来给一个要举办高尔夫比赛的树林砍树。树林由一个 m x n 的矩阵表示, 在这个矩阵中:

  • 0 表示障碍,无法触碰
  • 1 表示地面,可以行走
  • 比 1 大的数 表示有树的单元格,可以行走,数值表示树的高度

每一步,你都可以向上、下、左、右四个方向之一移动一个单位,如果你站的地方有一棵树,那么你可以决定是否要砍倒它。

你需要按照树的高度从低向高砍掉所有的树,每砍过一颗树,该单元格的值变为 1(即变为地面)。

你将从 (0, 0) 点开始工作,返回你砍完所有树需要走的最小步数。 如果你无法砍完所有的树,返回 -1 。

可以保证的是,没有两棵树的高度是相同的,并且你至少需要砍倒一棵树。

示例 1:

在这里插入图片描述

输入:forest = [[1,2,3],[0,0,4],[7,6,5]]
输出:6
解释:沿着上面的路径,你可以用 6 步,按从最矮到最高的顺序砍掉这些树。

思路

其实是昨天的每日一题,本质上是一个BFS,相比较于一般困难难度要低一点。

因为个人BFS确实薄弱一些,还是决定写上来。

思路还是比较清晰的:首先对所有非0单元格数值做排序,然后对于每个单元格做BFS寻找到达下一个点的最短路径。如果无法到达,则返回-1 。

BFS使用队列,把每个还没有搜索到的点依次放入队列,然后再弹出队列的头部元素当做当前遍历点。

BFS总共有两个模板:

1 . 如果不需要知道遍历层数,只需要访问完所有节点,模版如下:

while queue 不空:cur = queue.pop()if cur 有效且未被访问过:进行处理for 节点 in cur 的所有相邻节点:if 该节点有效:queue.push(该节点)

2 . 如果需要知道遍历层数,如下:

level = 0
while queue 不空:size = queue.size()while (size --) {cur = queue.pop()if cur 有效且未被访问过:进行处理for 节点 in cur的所有相邻节点:if 该节点有效:queue.push(该节点)}level ++;

本题需要知道最短路径,选用模版2 。


解题

python实现

class Solution:def cutOffTree(self, forest: List[List[int]]) -> int:M = len(forest)N = len(forest[0])trees = []for i in range(M):for j in range(N):if (forest[i][j] > 1):trees.append((forest[i][j], i, j))trees.sort()preX, preY = 0, 0res = 0for height, curX, curY in trees:steps = self.bfs(forest, preX, preY, curX, curY)if steps == -1:return -1res += stepspreX, preY = curX, curYreturn resdef bfs(self, forest, startX, startY, targetX, targetY):M = len(forest)N = len(forest[0])dirs = [(0, 1), (0, -1), (-1, 0), (1, 0)]steps = 0queue = collections.deque()queue.append((startX, startY))visited = set()visited.add((startX, startY))while queue:size = len(queue)for _ in range(size):curX, curY = queue.popleft()if curX == targetX and curY == targetY:return stepsfor d in dirs:nX = curX + d[0]nY = curY + d[1]if 0 <= nX < M and 0 <= nY < N and forest[nX][nY] != 0 and ((nX, nY) not in visited):queue.append((nX, nY))visited.add((nX, nY))steps += 1return -1

golang实现

var dir4 = []struct{ x, y int }{{-1, 0}, {1, 0}, {0, -1}, {0, 1}}func cutOffTree(forest [][]int) (ans int) {type pair struct{ dis, x, y int }trees := []pair{}for i, row := range forest {for j, h := range row {if h > 1 {trees = append(trees, pair{h, i, j})}}}sort.Slice(trees, func(i, j int) bool { return trees[i].dis < trees[j].dis })bfs := func(sx, sy, tx, ty int) int {m, n := len(forest), len(forest[0])vis := make([][]bool, m)for i := range vis {vis[i] = make([]bool, n)}vis[sx][sy] = trueq := []pair{{0, sx, sy}}for len(q) > 0 {p := q[0]q = q[1:]if p.x == tx && p.y == ty {return p.dis}for _, d := range dir4 {if x, y := p.x+d.x, p.y+d.y; 0 <= x && x < m && 0 <= y && y < n && !vis[x][y] && forest[x][y] > 0 {vis[x][y] = trueq = append(q, pair{p.dis + 1, x, y})}}}return -1}preX, preY := 0, 0for _, t := range trees {d := bfs(preX, preY, t.x, t.y)if d < 0 {return -1}ans += dpreX, preY = t.x, t.y}return
}

复杂度

时间复杂度 O ( m 2 ∗ n 2 ) \Omicron(m^{2}*n^{2}) O(m2n2),其中 m为矩阵的行数,n 为矩阵的列数。矩阵中最多有 m×n 颗树,对树的高度进行排序,时间复杂度为 O ( m × n × log ⁡ ( m × n ) ) O(m \times n \times \log (m \times n)) O(m×n×log(m×n)),利用广度优先搜索两颗树之间的最短距离需要的时间为 O ( m × n ) O ( m × n ) O(m \times n)O(m×n) O(m×n)O(m×n),因此总的时间复杂为 O ( m × n × log ⁡ ( m × n ) + m 2 ∗ n 2 ) = O ( m 2 ∗ n 2 ) O(m \times n \times \log (m \times n)+m^{2}*n^{2})=\Omicron(m^{2}*n^{2}) O(m×n×log(m×n)+m2n2)=O(m2n2)

空间复杂度 O ( m × n ) O(m \times n) O(m×n),其中m为矩阵的行数,n为矩阵的列数。矩阵中最多有 m × n m \times n m×n颗树,对树的高度进行排序,所需要的栈空间为 O ( log ⁡ ( m × n ) ) O(\log (m \times n)) O(log(m×n)),利用广度优先搜索队列中最多有 O ( m × n ) O(m \times n) O(m×n)个元素,标记已遍历过的元素需要的空间为 O ( m × n ) O(m \times n) O(m×n),因此总的空间复杂度为 O ( m × n ) O(m \times n) O(m×n)


总结

虽然思路很简单但是代码还是看晕了。。
遇到困难睡大觉系列

这篇关于【刷题】675. 为高尔夫比赛砍树的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/680948

相关文章

【每日刷题】Day113

【每日刷题】Day113 🥕个人主页:开敲🍉 🔥所属专栏:每日刷题🍍 🌼文章目录🌼 1. 91. 解码方法 - 力扣(LeetCode) 2. LCR 098. 不同路径 - 力扣(LeetCode) 3. 63. 不同路径 II - 力扣(LeetCode) 1. 91. 解码方法 - 力扣(LeetCode) //思路:动态规划。 cl

hot100刷题第1-9题,三个专题哈希,双指针,滑动窗口

求满足条件的子数组,一般是前缀和、滑动窗口,经常结合哈希表; 区间操作元素,一般是前缀和、差分数组 数组有序,更大概率会用到二分搜索 目前已经掌握一些基本套路,重零刷起leetcode hot 100, 套路题按套路来,非套路题适当参考gpt解法。 一、梦开始的地方, 两数之和 class Solution:#注意要返回的是数组下标def twoSum(self, nums: Lis

代码随想录刷题day25丨491.递增子序列 ,46.全排列 ,47.全排列 II

代码随想录刷题day25丨491.递增子序列 ,46.全排列 ,47.全排列 II 1.题目 1.1递增子序列 题目链接:491. 非递减子序列 - 力扣(LeetCode) 视频讲解:回溯算法精讲,树层去重与树枝去重 | LeetCode:491.递增子序列_哔哩哔哩_bilibili 文档讲解:https://programmercarl.com/0491.%E9%80%92%E

代码随想录刷题day24丨93.复原IP地址 ,78.子集 , 90.子集II

代码随想录刷题day24丨93.复原IP地址 ,78.子集 , 90.子集II 1.题目 1.1复原IP地址 题目链接:93. 复原 IP 地址 - 力扣(LeetCode) 视频讲解:回溯算法如何分割字符串并判断是合法IP?| LeetCode:93.复原IP地址_哔哩哔哩_bilibili 文档讲解:https://programmercarl.com/0093.%E5%A4%8

我们依旧在追梦的路上-山东省第六届ACM比赛总结

这场比赛从结果而言达到了预期(金牌),从过程而言和我的预期相差甚远(打的太乱,个人发挥很差),还好关键时刻队友抗住压力,负责后果真的不堪设想。 热身赛 热身赛纯粹测机器的,先把A,B,C草草水过(A题小写x打成大写的也是醉了),我和老高开始各种测机器,long long不出所料是lld的,试了一下除0和数组越界的re问题,发现没有re,只有wa(甚至数组越界还AC了),至于栈深的话也没过多追

【笔记】数据结构刷题09

快速排序 215. 数组中的第K个最大元素 class Solution {public:int findKthLargest(vector<int>& nums, int k) {return divide(nums,0,nums.size()-1,nums.size()-k);}int divide(vector<int>& nums,int left,int right,int k)

C语言:刷题日志(1)

一.阶乘计算升级版 本题要求实现一个打印非负整数阶乘的函数。 其中n是用户传入的参数,其值不超过1000。如果n是非负整数,则该函数必须在一行中打印出n!的值,否则打印“Invalid input”。 首先,知道阶乘是所有小于及等于该数的正整数的积,并且0的阶乘为1。那么我们先来个简单的阶乘计算吧。 #include<stdio.h>int Fact(int n){if (n <=

ACM比赛中如何加速c++的输入输出?如何使cin速度与scanf速度相当?什么是最快的输入输出方法?

在竞赛中,遇到大数据时,往往读文件成了程序运行速度的瓶颈,需要更快的读取方式。相信几乎所有的C++学习者都在cin机器缓慢的速度上栽过跟头,于是从此以后发誓不用cin读数据。还有人说Pascal的read语句的速度是C/C++中scanf比不上的,C++选手只能干着急。难道C++真的低Pascal一等吗?答案是不言而喻的。一个进阶的方法是把数据一下子读进来,然后再转化字符串,这种方法传说中

【每日刷题】Day112

【每日刷题】Day112 🥕个人主页:开敲🍉 🔥所属专栏:每日刷题🍍 🌼文章目录🌼 1. 1137. 第 N 个泰波那契数 - 力扣(LeetCode) 2. 面试题 08.01. 三步问题 - 力扣(LeetCode) 3. LCR 088. 使用最小花费爬楼梯 - 力扣(LeetCode) 1. 1137. 第 N 个泰波那契数 - 力扣(LeetCo

结合Python与GUI实现比赛预测与游戏数据分析

在现代软件开发中,用户界面设计和数据处理紧密结合,以提升用户体验和功能性。本篇博客将基于Python代码和相关数据分析进行讨论,尤其是如何通过PyQt5等图形界面库实现交互式功能。同时,我们将探讨如何通过嵌入式预测模型为用户提供赛果预测服务。 本文的主要内容包括: 基于PyQt5的图形用户界面设计。结合数据进行比赛预测。文件处理和数据分析流程。 1. PyQt5 图形用户界面设计