提取咒文
难度:
标签:
题目描述
English description is not available for the problem. Please switch to Chinese.
代码结果
运行时间: 1470 ms, 内存: 25.3 MB
/*
* 思路:
* 使用 Java Stream 进行 BFS 搜索每个字母的最短路径。
* 在 Java Stream 中对队列进行并行处理。
*/
import java.util.*;
import java.util.stream.*;
public class Solution {
public int minSteps(String[] matrix, String mantra) {
int rows = matrix.length;
int cols = matrix[0].length();
int[][] directions = {{0, 1}, {1, 0}, {0, -1}, {-1, 0}};
class Node {
int x, y, steps;
Node(int x, int y, int steps) {
this.x = x;
this.y = y;
this.steps = steps;
}
}
int totalSteps = 0;
int startX = 0, startY = 0;
for (char c : mantra.toCharArray()) {
Queue<Node> queue = new LinkedList<>();
boolean[][] visited = new boolean[rows][cols];
queue.add(new Node(startX, startY, 0));
visited[startX][startY] = true;
boolean found = false;
while (!queue.isEmpty()) {
List<Node> nodeList = new LinkedList<>();
queue.forEach(nodeList::add);
queue.clear();
nodeList.parallelStream().forEach(node -> {
if (matrix[node.x].charAt(node.y) == c) {
totalSteps += node.steps;
startX = node.x;
startY = node.y;
found = true;
queue.clear();
}
for (int[] dir : directions) {
int newX = node.x + dir[0];
int newY = node.y + dir[1];
if (newX >= 0 && newX < rows && newY >= 0 && newY < cols && !visited[newX][newY]) {
queue.add(new Node(newX, newY, node.steps + 1));
visited[newX][newY] = true;
}
}
});
if (found) break;
}
if (!found) {
return -1;
}
}
return totalSteps + mantra.length();
}
}
解释
方法:
该题解采用了宽度优先搜索(BFS)的策略来求解。首先,定义一个队列来存储探索状态,每个状态包含当前位置(x, y),当前正在尝试匹配的mantra中的字符索引(level),以及到达当前状态所需的步数(step)。整个矩阵的每个位置对应的每个字符索引都维护一个访问状态,以避免重复访问并陷入无限循环。从矩阵的左上角开始,对每个状态进行扩展:如果当前位置的字符与mantra中的当前字符匹配,则尝试移动到下一个字符,同时步数加一;否则,尝试向四个方向移动,每移动一步,步数也同样加一。这个过程持续进行,直到队列为空或成功匹配完所有字符。如果队列为空还未匹配完,返回-1表示无法完成提取。
时间复杂度:
O(m*n*L)
空间复杂度:
O(m*n*L)
代码细节讲解
🦆
为什么选择宽度优先搜索(BFS)而不是深度优先搜索(DFS)来解决这个问题?
▷🦆
在题解中提到的访问状态数组,每个位置存储的是什么信息?为什么需要这样一个三维数组来记录状态?
▷🦆
如何处理位于矩阵边缘的格子,在尝试向外扩展时不越界?
▷