(一).基础概念
最短路问题,是"图论"中的问题,当然,如果不知道图论问题,也不影响。
在这里,主要介绍"边权为1的最短路问题"。那么,什么是最短路问题?通过一张图来看

解决方法:从起点A开始,来一次BFS即可

(二).具体题目
1.迷宫中离入口最近的出口
1926. 迷宫中离入口最近的出口 - 力扣(LeetCode)

解法:bfs

java
class Solution {
int[] dx={1,-1,0,0};
int[] dy={0,0,1,-1};
boolean[][] visit;
public int nearestExit(char[][] maze, int[] entrance) {
int lenR=maze.length;
int lenC=maze[0].length;
visit=new boolean[lenR][lenC];
int count=0;
Queue<int[]> queue=new ArrayDeque<>();
queue.add(new int[]{entrance[0],entrance[1]});
visit[entrance[0]][entrance[1]]=true;
while (!queue.isEmpty()){
count++;
int size=queue.size();
for (int i = 0; i < size; i++) {
int[] poll = queue.poll();
int x=poll[0];
int y=poll[1];
for (int j = 0; j < 4; j++) {
int newX=x+dx[j];
int newY=y+dy[j];
if (newX>=0 && newX<lenR && newY>=0 && newY<lenC && maze[newX][newY]=='.' && !visit[newX][newY]){
if (newX==0 || newY==0 || newX==lenR-1 ||newY==lenC-1){
return count;
}
queue.add(new int[]{newX,newY});
visit[newX][newY]=true;
}
}
}
}
return -1;
}
}
2.最小基因变化

解法:BFS

java
class Solution {
public int minMutation(String startGene, String endGene, String[] bank) {
int count=0;
HashSet<String> hashSetBack=new HashSet<>(); //用于统计基因库里面的字符串
HashSet<String> hashSet=new HashSet<>(); //用于标记已经搜索过的位置
for(String str:bank){
hashSetBack.add(str);
}
Queue<String> queue=new ArrayDeque<>();
queue.add(startGene);
hashSet.add(startGene);
char[] chars={'A','C','T','G'};
while (!queue.isEmpty()){
count++;
int sz=queue.size();
for (int i = 0; i < sz; i++) {
String poll = queue.poll();
for (int j = 0; j < poll.length(); j++) {
char[] charArray = poll.toCharArray();
for (int k = 0; k < 4; k++) {
charArray[j]=chars[k];
String ans=new String(charArray);
if (!hashSet.contains(ans) && hashSetBack.contains(ans)){
if (ans.equals(endGene)){
return count;
}
hashSet.add(ans);
queue.add(ans);
}
}
}
}
}
return -1;
}
}
3.单词接龙

解法:bfs

java
class Solution {
public int ladderLength(String beginWord, String endWord, List<String> wordList) {
HashSet<String> hashSetList=new HashSet<>();
for (int i = 0; i < wordList.size(); i++) {
hashSetList.add(wordList.get(i));
}
if (!wordList.contains(endWord)){
return 0;
}
int count=0;
HashSet<String> hashSet=new HashSet<>(); //记录已访问的单词,防止重复走环
hashSet.add(beginWord);
Queue<String> queue=new ArrayDeque<>(); //bfs队列
queue.add(beginWord);
while (!queue.isEmpty()){
count++;
int sz=queue.size();
for (int i = 0; i < sz; i++) {
String poll = queue.poll();
int len=poll.length();
//逐个位置替换字符
for (int j = 0; j < len; j++) {
char[] charArray = poll.toCharArray();
//把第j位依次替换为 a~z
for (char k = 'a'; k <='z' ; k++) {
charArray[j]=k;
String ans=new String(charArray);
if (hashSetList.contains(ans) && !hashSet.contains(ans)){
//找到终点直接返回步数
if (ans.equals(endWord)){
return count+1;
}
queue.add(ans);
hashSet.add(ans); // 标记已访问
}
}
}
}
}
return 0;
}
}
4.为高尔夫比赛砍树

解法:bfs

java
class Solution {
int lenR;
int lenC;
public int cutOffTree(List<List<Integer>> forest) {
lenR=forest.size();
lenC=forest.get(0).size();
List<int[]> lists=new ArrayList<>();
for (int i = 0; i < lenR; i++) {
for (int j = 0; j < lenC; j++) {
if (forest.get(i).get(j)>1){
lists.add(new int[]{i,j});
}
}
}
Collections.sort(lists, new Comparator<int[]>() {
@Override
public int compare(int[] o1, int[] o2) {
return forest.get(o1[0]).get(o1[1])-forest.get(o2[0]).get(o2[1]);
}
});
int count=0;
int startX=0;
int startY=0;
for(int[] list:lists){
int posX=list[0];
int poxY=list[1];
int step=bfs(forest,startX,startY,posX,poxY);
if (step==-1){
return -1;
}
count+=step;
startX=posX; //更新坐标
startY=poxY;
}
return count;
}
int[] dx={1,-1,0,0};
int[] dy={0,0,1,-1};
private int bfs(List<List<Integer>> forest, int startX, int startY, int endX, int endY) {
if (startX==endX && startY==endY){
return 0;
}
Queue<int[]> queue=new ArrayDeque<>();
boolean[][] visit=new boolean[lenR][lenC];
int step=0;
queue.add(new int[]{startX,startY});
while (!queue.isEmpty()){
step++;
int sz=queue.size();
for (int i = 0; i < sz; i++) {
int[] poll = queue.poll();
int px=poll[0];
int py=poll[1];
for (int j = 0; j < 4; j++) {
int newX=px+dx[j];
int newY=py+dy[j];
if (newX>=0 && newX<lenR && newY>=0 && newY<lenC && forest.get(newX).get(newY)!=0 && !visit[newX][newY]){
if (newX==endX && newY==endY){
return step;
}
queue.add(new int[]{newX,newY});
visit[newX][newY]=true;
}
}
}
}
return -1;
}
}