不同路径 III
难度:
标签:
题目描述
代码结果
运行时间: 28 ms, 内存: 16.1 MB
/*
* 思路:
* 使用Java Stream编写递归搜索方法来实现相同的逻辑。
* 1. 找到起始位置和空格数量。
* 2. 使用递归和流来处理搜索和回溯。
*/
import java.util.stream.Stream;
public class UniquePathsIIIStream {
public int uniquePathsIII(int[][] grid) {
int empty = 0, sx = -1, sy = -1;
for (int i = 0; i < grid.length; i++) {
for (int j = 0; j < grid[i].length; j++) {
if (grid[i][j] == 0) {
empty++;
} else if (grid[i][j] == 1) {
sx = i;
sy = j;
}
}
}
return dfs(grid, sx, sy, empty);
}
private int dfs(int[][] grid, int x, int y, int empty) {
if (x < 0 || x >= grid.length || y < 0 || y >= grid[0].length || grid[x][y] == -1) {
return 0;
}
if (grid[x][y] == 2) {
return empty == -1 ? 1 : 0;
}
grid[x][y] = -1;
empty--;
int[] directions = {-1, 0, 1, 0, -1};
int paths = Stream.of(1, 2, 3, 4)
.mapToInt(i -> dfs(grid, x + directions[i], y + directions[i - 1], empty))
.sum();
grid[x][y] = 0;
empty++;
return paths;
}
}
解释
方法:
题解采用深度优先搜索(DFS)策略,通过递归来探索所有可能的路径。首先,算法寻找起始点(值为1的格子),并计算网格中空白格子(值为0)的数量。之后,从起始点出发,向四个方向探索,每走过一个空白格子,就将其标记为不可再走(设为-1)。如果到达终点(值为2的格子),检查是否所有空白格子都已经走过,即剩余格子数left是否为0。如果是,说明找到了一条有效路径。每次探索完成后,将当前格子重置回可走状态,以便其他路径探索时使用。最终,返回从起始点到终点的所有有效路径的数量。
时间复杂度:
O(4^k)
空间复杂度:
O(k)
代码细节讲解
🦆
为什么在到达终点时要检查剩余格子数left是否为0来判断路径的有效性?
▷🦆
在DFS中,你是如何处理网格边界以及障碍(`grid[x][y] < 0`)的情况的?
▷🦆
为什么在每次递归完成后需要将当前格子重置回可走状态(即设置为0)?
▷🦆
题解中提到每个格子至多被访问一次,这是否意味着算法能够避免不必要的重复计算?
▷相关问题
解数独
编写一个程序,通过填充空格来解决数独问题。
数独的解法需 遵循如下规则:
- 数字
1-9
在每一行只能出现一次。 - 数字
1-9
在每一列只能出现一次。 - 数字
1-9
在每一个以粗实线分隔的3x3
宫内只能出现一次。(请参考示例图)
数独部分空格内已填入了数字,空白格用 '.'
表示。
示例 1:

输入:board = [["5","3",".",".","7",".",".",".","."],["6",".",".","1","9","5",".",".","."],[".","9","8",".",".",".",".","6","."],["8",".",".",".","6",".",".",".","3"],["4",".",".","8",".","3",".",".","1"],["7",".",".",".","2",".",".",".","6"],[".","6",".",".",".",".","2","8","."],[".",".",".","4","1","9",".",".","5"],[".",".",".",".","8",".",".","7","9"]] 输出:[["5","3","4","6","7","8","9","1","2"],["6","7","2","1","9","5","3","4","8"],["1","9","8","3","4","2","5","6","7"],["8","5","9","7","6","1","4","2","3"],["4","2","6","8","5","3","7","9","1"],["7","1","3","9","2","4","8","5","6"],["9","6","1","5","3","7","2","8","4"],["2","8","7","4","1","9","6","3","5"],["3","4","5","2","8","6","1","7","9"]] 解释:输入的数独如上图所示,唯一有效的解决方案如下所示:![]()
提示:
board.length == 9
board[i].length == 9
board[i][j]
是一位数字或者'.'
- 题目数据 保证 输入数独仅有一个解
不同路径 II
一个机器人位于一个 m x n
网格的左上角 (起始点在下图中标记为 “Start” )。
机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角(在下图中标记为 “Finish”)。
现在考虑网格中有障碍物。那么从左上角到右下角将会有多少条不同的路径?
网格中的障碍物和空位置分别用 1
和 0
来表示。
示例 1:

输入:obstacleGrid = [[0,0,0],[0,1,0],[0,0,0]]
输出:2
解释:3x3 网格的正中间有一个障碍物。
从左上角到右下角一共有 2
条不同的路径:
1. 向右 -> 向右 -> 向下 -> 向下
2. 向下 -> 向下 -> 向右 -> 向右
示例 2:

输入:obstacleGrid = [[0,1],[0,0]] 输出:1
提示:
m == obstacleGrid.length
n == obstacleGrid[i].length
1 <= m, n <= 100
obstacleGrid[i][j]
为0
或1
单词搜索 II
给定一个 m x n
二维字符网格 board
和一个单词(字符串)列表 words
, 返回所有二维网格上的单词 。
单词必须按照字母顺序,通过 相邻的单元格 内的字母构成,其中“相邻”单元格是那些水平相邻或垂直相邻的单元格。同一个单元格内的字母在一个单词中不允许被重复使用。
示例 1:

输入:board = [["o","a","a","n"],["e","t","a","e"],["i","h","k","r"],["i","f","l","v"]], words = ["oath","pea","eat","rain"] 输出:["eat","oath"]
示例 2:

输入:board = [["a","b"],["c","d"]], words = ["abcb"] 输出:[]
提示:
m == board.length
n == board[i].length
1 <= m, n <= 12
board[i][j]
是一个小写英文字母1 <= words.length <= 3 * 104
1 <= words[i].length <= 10
words[i]
由小写英文字母组成words
中的所有字符串互不相同