代码拉取完成,页面将自动刷新
import java.util.ArrayList;
import java.util.List;
/**
* 原题 https://leetcode.com/problems/shortest-path-to-get-all-keys/
* 1. 广度优先搜索
* 2. 深度优先搜索 timeout
*/
public class _864 {
static class Solution1 {
public int shortestPathAllKeys(String[] grid) {
//(i,j,state) 三元组
List<int[]> cur = new ArrayList<>();
int endState = 0;
int step = 0;
for (int i = 0; i < grid.length; i++) {
for (int j = 0; j < grid[0].length(); j++) {
char ch = grid[i].charAt(j);
if (ch >= 'a' && ch <= 'f') {
endState |= (1 << ch - 'a');
}
if (ch == '@') {
cur.add(new int[]{i, j, 0});
}
}
}
boolean[][][] v = new boolean[grid.length][grid[0].length()][endState];
for (int[] node : cur) {
v[node[0]][node[1]][0] = true;
}
int[][] dirs = {
{0, 1},
{0, -1},
{-1, 0},
{1, 0},
};
while (cur.size() > 0) {
List<int[]> next = new ArrayList<>();
for (int[] node : cur) {
int i = node[0];
int j = node[1];
int state = node[2];
char ch = grid[i].charAt(j);
if (ch >= 'a' && ch <= 'f') {
state |= 1 << ch - 'a';
if (state == endState) {
return step;
}
}
for (int[] dir : dirs) {
int newI = i + dir[0];
int newJ = j + dir[1];
if (newI < 0 || newJ < 0 || newI >= grid.length || newJ >= grid[0].length()) {
continue;
}
char newCh = grid[newI].charAt(newJ);
if (newCh == '#' || v[newI][newJ][state]) continue;
if (newCh >= 'A' && newCh <= 'F') {
if ((state & (1 << newCh - 'A')) == 0) continue;
}
v[newI][newJ][state] = true;
next.add(new int[]{newI, newJ, state});
}
}
cur = next;
step++;
}
return -1;
}
}
static class Solution2 {
//深度优先搜索行不通,决策的分支太多,导致超时。尝试使用动态规划记录分支,但是没法定义状态
public int shortestPathAllKeys(String[] grid) {
//最难的在于,走重复的路
// 根据key的状态走重复的路
// i,j,state
// 最多 64种状态.
int endState = 0;
List<int[]> start = new ArrayList<>();
boolean[] keys = new boolean[6];
for (int i = 0; i < grid.length; i++) {
for (int j = 0; j < grid[0].length(); j++) {
char ch = grid[i].charAt(j);
if (ch >= 'a' && ch <= 'f') {
keys[ch - 'a'] = true;
}
if (ch == '@') {
start.add(new int[]{i, j});
}
}
}
for (int i = 0; i < keys.length; i++) {
if (keys[i]) endState += (1 << i);
}
int min = Integer.MAX_VALUE;
for (int[] s : start) {
min = Math.min(min, dfs(0, new boolean[endState][grid.length][grid[0].length()], grid, s[0], s[1], 0, endState));
}
return min == Integer.MAX_VALUE ? -1 : min;
}
public int dfs(int state, boolean[][][] v, String[] grid, int i, int j, int step, int endState) {
if (i < 0 || i >= grid.length || j < 0 || j >= grid[0].length()) return Integer.MAX_VALUE;
if (v[state][i][j]) return Integer.MAX_VALUE;
char cur = grid[i].charAt(j);
if (cur == '#') return Integer.MAX_VALUE;
if (cur >= 'A' && cur <= 'F') {
if ((state & (1 << cur - 'A')) == 0) return Integer.MAX_VALUE;
}
int newState = state;// 这里一定要小心,必须要用新的变量接收,否则回溯时,状态不一样
if (cur >= 'a' && cur <= 'f') {
newState |= (1 << cur - 'a');
if (newState == endState) {
return step;
}
}
v[state][i][j] = true;
v[newState][i][j] = true;
int[][] dirs = {
{-1, 0},
{1, 0},
{0, -1},
{0, 1}
};
int min = Integer.MAX_VALUE;
for (int[] dir : dirs) {
min = Math.min(min, dfs(newState, v, grid, i + dir[0], j + dir[1], step + 1, endState));
}
v[state][i][j] = false;
v[newState][i][j] = false;
return min;
}
}
}
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。