返回
从一个“红心”构筑多彩创意,教你突破自我!
前端
2023-09-11 07:07:49
在一个方格中,有一颗红心,你只能沿着方格的边前进。在旅途中,你遇到各种障碍,必须绕过这些障碍才能到达目的地。究竟有多少种路线可以让你到达终点呢?
为了解决这个问题,你可以使用“栈”数据结构,将每个点存储起来。当进入一个点时,先将它压入栈中,然后检查它的左、右两个点是否可以走。如果可以,则将其分别压入栈中。最后,当你到达终点 (m - 1, n - 1) 时,将结果计数器 ret 加 1。将该点从栈中弹出,并返回到上一层,以此类推,直到栈中所有点都被弹出。
以一个 3x3 的方格为例:
1 2 3
4 5 6
7 8 9
使用栈进行遍历:
1. 压入点 (1, 1)
2. 检查点 (1, 1) 的左、右点是否可走。
- 左点 (1, 0) 可走,将其压入栈中。
- 右点 (1, 2) 可走,将其压入栈中。
3. 压入点 (1, 0)
4. 检查点 (1, 0) 的左、右点是否可走。
- 左点 (0, 0) 不可走。
- 右点 (1, 1) 已访问过,跳过。
5. 弹出点 (1, 0)
6. 压入点 (1, 2)
7. 检查点 (1, 2) 的左、右点是否可走。
- 左点 (1, 1) 已访问过,跳过。
- 右点 (2, 2) 可走,将其压入栈中。
8. 压入点 (2, 2)
9. 检查点 (2, 2) 的左、右点是否可走。
- 左点 (2, 1) 可走,将其压入栈中。
- 右点 (3, 2) 不可走。
10. 压入点 (2, 1)
11. 检查点 (2, 1) 的左、右点是否可走。
- 左点 (2, 0) 可走,将其压入栈中。
- 右点 (3, 1) 可走,将其压入栈中。
12. 压入点 (2, 0)
13. 检查点 (2, 0) 的左、右点是否可走。
- 左点 (1, 0) 已访问过,跳过。
- 右点 (2, 1) 已访问过,跳过。
14. 弹出点 (2, 0)
15. 弹出点 (2, 1)
16. 弹出点 (2, 2)
17. 弹出点 (1, 2)
18. 到达终点 (2, 2),计数器 ret 加 1。
19. 弹出点 (1, 1)
20. 弹出点 (1, 0)
21. 弹出点 (1, 1)
22. 所有点均已弹出,算法结束。
通过这种方式,最终计数器 ret 的值就是从 (1, 1) 到 (m - 1, n - 1) 的路径数量。
除了使用栈之外,还可以使用队列来解决这个问题。队列与栈的区别在于,队列遵循“先进先出”的原则,而栈遵循“先进后出”的原则。
使用队列进行遍历:
1. 入队点 (1, 1)
2. 检查点 (1, 1) 的左、右点是否可以走。
- 左点 (1, 0) 可走,将其入队。
- 右点 (1, 2) 可走,将其入队。
3. 出队点 (1, 1)
4. 入队点 (1, 0)
5. 检查点 (1, 0) 的左、右点是否可走。
- 左点 (0, 0) 不可走。
- 右点 (1, 1) 已访问过,跳过。
6. 出队点 (1, 0)
7. 入队点 (1, 2)
8. 检查点 (1, 2) 的左、右点是否可走。
- 左点 (1, 1) 已访问过,跳过。
- 右点 (2, 2) 可走,将其入队。
9. 出队点 (1, 2)
10. 入队点 (2, 2)
11. 检查点 (2, 2) 的左、右点是否可走。
- 左点 (2, 1) 可走,将其入队。
- 右点 (3, 2) 不可走。
12. 出队点 (2, 2)
13. 入队点 (2, 1)
14. 检查点 (2, 1) 的左、右点是否可走。
- 左点 (2, 0) 可走,将其入队。
- 右点 (3, 1) 可走,将其入队。
15. 出队点 (2, 1)
16. 入队点 (2, 0)
17. 检查点 (2, 0) 的左、右点是否可走。
- 左点 (1, 0) 已访问过,跳过。
- 右点 (2, 1) 已访问过,跳过。
18. 出队点 (2, 0)
19. 入队点 (3, 1)
20. 检查点 (3, 1) 的左、右点是否可走。
- 左点 (2, 1) 已访问过,跳过。
- 右点 (4, 1) 不可走。
21. 出队点 (3, 1)
22. 所有点均已出队,算法结束。
通过这种方式,最终计数器 ret 的值也是从 (1, 1) 到 (m - 1, n - 1) 的路径数量。
使用栈或队列来解决这个问题的复杂度都是 O(mn),其中 m 是方格的行数,n 是方格的列数。