大家好,我是 @负雪明烛。点击右上方的「+关注」↗,优质题解不间断!
题目大意
题意很模糊,你可能没读懂!!
让我们砍树(数值大于 1 的是树🌲),但是砍树有个规则,必须从低向高砍,问砍完所有树的移动步数。
题目给出的示例不够清晰。看看我下面这几张图,应该秒懂了。
解题方法
分析
根据题意,总的移动步数为:从起点到最低的树的最少步数 + 从最低的树到第 2 低的树的最少步数 + 从第 2 低的树到第 3 低的树的最少步数 + … 直至所有树被砍完。
用图表示就是如下:
求最少移动步数,一般可以使用 BFS 去做。
分享 BFS 模板:
BFS使用队列,把每个还没有搜索到的点依次放入队列,然后再弹出队列的头部元素当做当前遍历点。
BFS总共有两个模板:
模板一:
如果不需要确定当前遍历到了哪一层,只需要访问完所有节点就可以时。
BFS 模板如下:
while queue 不空:
cur = queue.pop()
if cur 有效且未被访问过:
进行处理
for 节点 in cur 的所有相邻节点:
if 该节点有效:
queue.push(该节点)
模板二:
如果要确定当前遍历到了哪一层,需要知道最少移动步数时,BFS 模板如下。
这里增加了 level
表示当前遍历到二叉树中的哪一层了,也可以理解为在一个图中,现在已经走了多少步了。size
表示在当前遍历层有多少个元素,也就是队列中的元素数,我们把这些元素一次性遍历完,即把当前层的所有元素都向外走了一步。
level = 0
while queue 不空:
size = queue.size()
while (size --) {
cur = queue.pop()
if cur 有效且未被访问过:
进行处理
for 节点 in cur的所有相邻节点:
if 该节点有效:
queue.push(该节点)
}
level ++;
上面两个是通用模板,在任何题目中都可以用,是要理解并且记住的!
本题需要知道求最少步数,因此使用模板二。
代码
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, 0
res = 0
for height, curX, curY in trees:
steps = self.bfs(forest, preX, preY, curX, curY)
if steps == -1:
return -1
res += steps
preX, preY = curX, curY
return res
def bfs(self, forest, startX, startY, targetX, targetY):
M = len(forest)
N = len(forest[0])
dirs = [(0, 1), (0, -1), (-1, 0), (1, 0)]
steps = 0
queue = 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 steps
for 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 += 1
return -1
复杂度
- 时间复杂度:,可能有 棵树,每次移动最多 次。
- 空间复杂度:。
总结
- 理解题意啊!!
我是 @负雪明烛 ,刷算法题 1000 多道,写了 1000 多篇算法题解,收获阅读量 300 万。
关注我,你将不会错过我的精彩动画题解、面试题分享、组队刷题活动,进入主页 @负雪明烛 右侧有刷题组织,从此刷题不再孤单。
- 在刷题的时候,如果你不知道该怎么刷题,可以看 LeetCode 应该怎么刷?
- 如果你觉得题目太多,想在短时间内快速提高,可以看 LeetCode 最经典的 100 道题。
- 送你一份刷题的代码模板:【LeetCode】代码模板,刷题必会
- 我写的 1000 道 LeetCode 题解,都在这里了,免费拿走。