864. Shortest Path to Get All Keys (H)
Input: grid = ["@.a.#","###.#","b.A.B"]
Output: 8
Explanation: Note that the goal is to obtain all the keys not to open all the locks.Solution:
Last updated
Input: grid = ["@.a.#","###.#","b.A.B"]
Output: 8
Explanation: Note that the goal is to obtain all the keys not to open all the locks.Last updated
Input: grid = ["@..aA","..B#.","....b"]
Output: 6Input: grid = ["@Aa"]
Output: -1class Solution {
public int shortestPathAllKeys(String[] grid) {
String emptyString = " ";
String all6Keys = "abcdef";
Queue<Node> queue = new LinkedList<>();
Set<String> visited = new HashSet<>();
int startX =0;
int startY = 0;
int maxLen = 0;
for(int i = 0; i< grid.length; i++)
{
for(int j = 0; j< grid[0].length(); j++)
{
char c = grid[i].charAt(j);
if(c >='a' && c <='f')
{
maxLen = Math.max(maxLen, c - 'a' + 1);
}
if(c == '@')
{
startX = i;
startY = j;
}
}
}
String allKeys = all6Keys.substring(0, maxLen);
Node startNode = new Node(startX, startY, new StringBuilder(emptyString.substring(0, maxLen)));
queue.offer(startNode);
visited.add(startNode.toString());
int step = 0;
int[] directX = {-1,1,0,0};
int[] directY = {0,0,-1,1};
while(!queue.isEmpty())
{
int size = queue.size();
for(int j= 0;j< size; j++)
{
Node current = queue.poll();
if(allKeys.equals(current.keySb.toString()))
{
return step;
}
for(int i = 0; i< 4; i++)
{
int nextX = current.x + directX[i];
int nextY = current.y + directY[i];
// 这里不能如下用, 要再new 一个新的出来。
//StringBuilder currentKeys = current.keySb;
StringBuilder currentKeys = new StringBuilder(current.keySb);
if(isBound(grid, nextX, nextY) && grid[nextX].charAt(nextY) != '#')
{
Character c = grid[nextX].charAt(nextY);
// encounter lock and current don't have key
if(isLock(c) && currentKeys.charAt(Character.toLowerCase(c)-'a') != Character.toLowerCase(c))
{
continue;
}
// encounter key, add it in the queue and acquiredKeys
if(isKey(c))
{
currentKeys.setCharAt(c-'a', c);
}
Node adj = new Node(nextX, nextY, currentKeys);
if(!visited.contains(adj.toString()))
{
queue.offer(adj);
visited.add(adj.toString());
}
}
}
}
step++;
}
return -1;
}
public boolean isKey(Character c)
{
if(c >= 'a' && c <= 'f')
{
return true;
}
return false;
}
public boolean isLock(Character c)
{
if(c >= 'A' && c <= 'F')
{
return true;
}
return false;
}
public boolean isBound(String[] grid, int x, int y)
{
return x >= 0 && x < grid.length && y >= 0 && y < grid[0].length();
}
}
class Node
{
int x;
int y;
StringBuilder keySb;
public Node(int x, int y, StringBuilder sb)
{
this.x = x;
this.y = y;
this.keySb = sb;
}
public String toString()
{
//这里一定要append ",", 不然当keySb is " ", 前面的空格会消失
return new StringBuilder(this.keySb).append(",").append(this.x).append(",").append(this.y).toString();
//return new StringBuilder(this.keySb).append(this.x).append(this.y).toString();
}
}
import java.util.*;
public class ShortPathGetOneKey {
public static void main(String[] args)
{
char[][] maze = {{'0','a','0'}, {'A','1','1'}, {'0','0','0'}};
int path = getShortPath(maze);
// output 6;
System.out.println(path);
}
public static int getShortPath(char[][] maze)
{
int m = maze.length;
int n = maze[0].length;
Set<String> visited = new HashSet<>();
Queue<Node> queue = new LinkedList<Node>();
Node startNode = new Node(0, 0, false);
queue.offer(startNode);
visited.add(startNode.toString());
int step = 0;
int[] directX = {-1, 1, 0, 0};
int[] directY = {0, 0, -1, 1};
while(!queue.isEmpty())
{
int size = queue.size();
for(int j = 0; j< size; j++)
{
Node current = queue.poll();
System.out.println(current.toString());
if(current.x == m-1 && current.y == n-1)
{
return step;
}
for(int i = 0; i< 4; i++)
{
int nextX = current.x + directX[i];
int nextY = current.y + directY[i];
if(nextX <0 || nextX >=m || nextY <0 || nextY >=n)
{
continue;
}
char c = maze[nextX][nextY];
if(c == '1')
{
continue;
}
if(c == 'A' && !current.isGetKey)
{
continue;
}
Node adj = new Node(nextX, nextY, current.isGetKey);
if(c == 'a')
{
adj.isGetKey = true;
}
if(!visited.contains(adj.toString()))
{
queue.offer(adj);
visited.add(adj.toString());
}
}
}
step++;
}
return -1;
}
}
class Node
{
int x;
int y;
boolean isGetKey;
public Node(int x, int y, boolean isGetKey)
{
this.x = x;
this.y = y;
this.isGetKey = isGetKey;
}
public String toString()
{
if(this.isGetKey)
{
return new StringBuilder().append(x).append(y).append("1").toString();
}
return new StringBuilder().append(x).append(y).append("0").toString();
}
}