回溯算法之广度优先遍历

news/2024/10/17 23:33:21/

目录

迷宫问题

N叉树的层序遍历

 腐烂的橘子

单词接龙

 最小基因变化

 打开转盘锁


迷宫问题

假设有一个迷宫,里面有障碍物,迷宫用二维矩阵表示,标记为0的地方表示可以通过,标记为1的地方表示障碍物,不能通过。现在给一个迷宫出口,让你判断是否可以从入口进来之后,走出迷宫,每次可以向任意方向走。

步骤:

1.创建

        1.创建队列

        2.创建book

        3.创建方向矩阵

2.开始位置

        1.开始位置标记遍历过

        2.把开始坐标放到队列中

3.遍历队列

        1.得到队首元素

        2.如果和出口元素相同,范湖true

        3.搜索新的位置

                1.得到位置

                2.判断位置是否合法

                3.如果没有遍历过是通路-->放入队列,标记为1

import java.util.LinkedList;
import java.util.Queue;
import java.util.Scanner;/*** @author KYF* @create 2023-06-03*/
class pair{public int x;public int y;public pair(int x,int y){this.x=x;this.y=y;}
}
//0可以通过,1有障碍
public class Test {public static boolean dfs(int[][] mat,int startx,int starty,int endx,int endy){//队列保存搜索到的位置Queue<pair> posQ=new LinkedList<>();posQ.offer(new pair(startx,starty));int row=mat.length;int col=mat[0].length;int[][] book=new int[row][col];book[startx][starty]=1;posQ.offer(new pair(startx,starty));int[][] next={{0,1},{0,-1},{-1,0},{1,0}};//搜索  -->要把队列中的所有元素都搜索完while(!posQ.isEmpty()){pair curPos=posQ.poll();if(curPos.x==endx && curPos.y==endy)return true;//搜索新的位置for (int i = 0; i < 4; i++) {int nx=curPos.x+next[i][0];int ny=curPos.y+next[i][1];if(nx<0 || nx>=row || ny<0 || ny>=col){continue;}//保存新的位置if(book[nx][ny]==0  && mat[nx][ny]==0){posQ.offer(new pair(nx,ny));book[nx][ny]=1;}}}return false;}public static void main(String[] args) {int[][] mat= {{0, 0, 1, 0},{1, 0, 0, 1},{0,0,0,0},{1,1,0,0}};while(true){System.out.println("输入开始位置和结束位置");Scanner sc=new Scanner(System.in);int startx=sc.nextInt();int starty=sc.nextInt();int endx=sc.nextInt();int endy=sc.nextInt();boolean a=dfs(mat,startx,starty,endx,endy);System.out.println(a);}}
}

N叉树的层序遍历

思路:创建链表和队列,遍历队列,把队列元素取出,值放入链表中,把元素的孩子放到对列中

步骤:

        1.创建队列  和链表

        2.把root结点放入队列

        3.遍历队列

                1.得到队列长度

                2.取出全部元素,一个一个遍历

                3.创建链表,把结点放入链表

                4.把结点的孩子放入队列中

        4.把新的链表存入大链表中

class Solution {public List<List<Integer>> levelOrder(Node root) {List<List<Integer>> list=new ArrayList<>();Queue<Node> q=new LinkedList<>();if(root==null){return list;}q.offer(root);while(!q.isEmpty()){int size=q.size();List<Integer> newL=new ArrayList();while(size--!=0){Node cur=q.poll();newL.add(cur.val);for(Node n:cur.children){q.offer(n);}}list.add(newL);}return list;}
}

 腐烂的橘子

  •  创建队列,用于深度遍历
  • 找到所有腐烂的(值为2),放入队列中
  • 创建step,用于记录步数
  • 遍历队列,直到队列为0,结束
    • 定义flag,用于记录是否当前是否蔓延到新的橘子
    • 得到当前队列的个数,保证当前这次的元素能全部遍历到
      • flag=1  说明有新的被蔓延,放入队列中
      • 遍历四个方向得到新的位置
      • 如果位置不合法或者不是新的橘子,continue
      • flag=1,当前位置标记为腐烂,放入队列中
    • 如果flag=1(这一层遍历完),step++
  • 遍历所以,如果还有新鲜橘子则返回-1
  • 返回step
class pair{int x;int y;public pair(int x,int y){this.x=x;this.y=y;}}
class Solution {public int orangesRotting(int[][] grid) {int row=grid.length;int col=grid[0].length;int[][] next={{0,1},{0,-1},{1,0},{-1,0}};Queue<pair> q=new LinkedList<>();for(int i=0;i<row;i++){for(int j=0;j<col;j++){if(grid[i][j]==2){q.offer(new pair(i,j));}}}int step=0;while(!q.isEmpty()){int size=q.size();int flag=0;while(size--!=0){pair cur=q.poll();for(int i=0;i<4;i++){int nx=cur.x+next[i][0];int ny=cur.y+next[i][1];if(nx<0 || nx>=row || ny<0 || ny>=col || grid[nx][ny]!=1){continue;}flag=1;grid[nx][ny]=2;q.offer(new pair(nx,ny));}}if(flag==1){step++;}}for(int i=0;i<row;i++){for(int j=0;j<col;j++){if(grid[i][j]==1){return -1;}}}return step;}
}

单词接龙

计数有第一个,开始为1,如果有新的++ 

  •  创建两个set,一个存放字典,一个存遍历过的字符串,创建队列用于广度遍历
  • 把开始字符串放入队列中
  • 遍历队列
    • 得到队列长度,把当前层的都遍历到
      • 得到字符串
      • 如果和结束相等,返回step
      • 遍历字符串的字符分别替换成别的字母
      • 如果在字典中,没有遍历过,放入队列,标记为遍历过
    • step++
  • 还没有结束,返回0

  public int ladderLength(String beginWord, String endWord, List<String> wordList) {int step=1;//开始不包含在字典中Set<String> book=new HashSet<>();Set<String> dict=new HashSet<>();for(String str:wordList){dict.add(str);}Queue<String> q=new LinkedList<>();q.offer(beginWord);while(!q.isEmpty()){int n=q.size();while(n--!=0){String cur=q.poll();if(cur.contains(endWord)){return step;}for(int i=0;i<cur.length();i++){StringBuilder s=new StringBuilder(cur);for(char ch='a';ch<='z';ch++){s.setCharAt(i,ch);String s1=s.toString();if(dict.contains(s1) && !book.contains(s1) ){q.offer(s1);book.add(s1);}}}}step++;}return 0;}

 最小基因变化

 计数没有算第一个,开始为0,如果有新的在++

  •  创建两个set,一个存放字典,一个存遍历过的字符串,创建队列用于广度遍历
  • step==0
  • 把开始字符串放入队列中
  • 遍历队列
    • 得到队列长度,把当前层的都遍历到
      • 得到字符串
      • 如果和结束相等,返回step
      • 遍历字符串的字符分别替换成别的字母
      • 如果在字典中,没有遍历过,放入队列,标记为遍历过
    • step++
  • 还没有结束,返回0
public int minMutation(String startGene, String endGene, String[] bank) {int step=0;Set<String> book=new HashSet<>();Set<String> dict=new HashSet<>();Queue<String> q=new LinkedList<>();q.offer(startGene);for(String s:bank){dict.add(s);}char[] ch={'A','C','G','T'};while(!q.isEmpty()){int size=q.size();while(size--!=0){String cur=q.poll();if(cur.contains(endGene)){return step;}for(int i=0;i<cur.length();i++){StringBuilder str1=new StringBuilder(cur);for(int j=0;j<4;j++){str1.setCharAt(i,ch[j]);String s1=str1.toString();if(dict.contains(s1) && !book.contains(s1)){q.offer(s1);book.add(s1);}}}}step++;}return -1;}

 打开转盘锁

 

  1. 创建
    1. step=0 记录步数  计数没有包含第一个
    2. queue存放数据
    3. set book(是否遍历过) dead(存放死亡字符串)
  2. 把开始位置放入队列,和book中
  3. deadends放入dead中
  4. 遍历队列
    1. 得到队列长度,保证都遍历到
      1. 取出队首字符串
      2. 如果和目标数字相同,则返回步数
      3. 遍历字符串,每一个字符串的每个字符
      4. 两个int型变量记录当前位置,分别表示向上波动和向下波动
      5. 向上:如果是9.-->0,不是++ 向下:如果是0-->9,不是--
      6. 创建两个stringbuilder.把对应位置换掉
      7. 如果不和任何一个相同,没有遍历过
      8. 放入队列,book中
    2. step++
  5. return 0
 public int openLock(String[] deadends, String target) {//计数没有包含第一个int step=0;Set<String> book=new HashSet<>();Set<String> dead=new HashSet<>();for(String str:deadends){dead.add(str);}if(dead.contains("0000")){return -1;}Queue<String> q=new LinkedList<>();q.offer("0000");book.add("0000");while(!q.isEmpty()){int size=q.size();while(size--!=0){String cur=q.poll();if(cur.contains(target)){return step;}//转动for(int i=0;i<4;i++){char new1=cur.charAt(i);char new2=cur.charAt(i);//往上转if(new1=='9'){new1='0';}else{new1++;}//往下转if(new2=='0'){new2='9';}else{new2--;}//替换StringBuilder str1=new StringBuilder(cur);StringBuilder str2=new StringBuilder(cur);str1.setCharAt(i,new1);str2.setCharAt(i,new2);String s1=str1.toString();String s2=str2.toString();//判断if(!dead.contains(s1) && !book.contains(s1)){q.offer(s1);book.add(s1);} if(!dead.contains(s2) && !book.contains(s2)){q.offer(s2);book.add(s2);}}
}step++;}return -1;}


http://www.ppmy.cn/news/386829.html

相关文章

回归预测 | MATLAB实现基于GRU-AdaBoost门控循环单元结合AdaBoost多输入单输出回归预测

回归预测 | MATLAB实现基于GRU-AdaBoost门控循环单元结合AdaBoost多输入单输出回归预测 目录 回归预测 | MATLAB实现基于GRU-AdaBoost门控循环单元结合AdaBoost多输入单输出回归预测预测效果基本介绍模型描述程序设计参考资料 预测效果 基本介绍 1.MATLAB实现基于GRU-AdaBoost门…

python将tif从wgs84转gcj02

# mark: 主要是dem从wgs84转成gcj02&#xff0c;步骤为wgs84的4326转成3857&#xff0c;之后投影进行偏移&#xff0c;再将偏移后的3857转成4326from osgeo import gdal, osr# 经纬度转投影 def tif4326To3857(input_file, output_file):options gdal.WarpOptions(formatGTiff…

【软件分析/静态分析】chapter3 课程03/04 数据流分析的应用(Data Flow Analysis)

&#x1f517; 课程链接&#xff1a;李樾老师和谭天老师的&#xff1a;南京大学《软件分析》课程03&#xff08;Data Flow Analysis I&#xff09;_哔哩哔哩_bilibili 南京大学《软件分析》课程04&#xff08;Data Flow Analysis II&#xff09;_哔哩哔哩_bilibili 这篇文章总结…

MySQL如何保证数据的可靠性(保证数据不丢失)

1. 结论&#xff1a; 只要redo log 和 binlog 保证持久化到磁盘&#xff0c;就能确保MySQL异常重启后&#xff0c;数据可以恢复。 2. 机制 WAL机制&#xff0c;&#xff08;Write Ahead Log&#xff09;&#xff1a; 事务先写入日志&#xff0c;后持久化到磁盘。 3. binlog…

【MySql】基本查询

文章目录 插入操作insert查询操作selectselect查询where条件判断order by排序limit筛选分页结果 更新操作update删除操作delete插入查询结果 CRUD : Create(创建), Retrieve(读取)&#xff0c;Update(更新)&#xff0c;Delete&#xff08;删除&#xff09; 先创建提供一张表&am…

次时代的终端产品

看到一位领导报告&#xff0c;其中一些文字觉得总结十分到位&#xff0c;在此做一下记录。 工业革命下的产品&#xff0c;每一个时代都有这个时代进入千家万户的终端产品。 第一次工业革命是机械化&#xff0c;当时进入千家万户的&#xff0c;是200多年前开始出现的自行车、缝纫…

黑客松必备|Bear Necessities Hackathon Office Hours汇总

由Moonbeam和AWS Startups联合主办的Bear Necessities Hackathon黑客松启动仪式已于5月30日举行。本次黑客松将历时约1个月的时间&#xff0c;包含6个挑战&#xff0c;分别由Moonbeam基金会、Chainlink、StellaSwap、SubQuery、Biconomy提供赞助&#xff0c;总奖池超过5万美金。…

全球限量1000台!京东联手格力首推全AI定制冰箱 618开售

又是一年京东店庆月。每年618京东都会玩一些新花样&#xff0c;为各位剁手党提供价格优惠、品质优良的好产品。今年京东与“家电一姐”格力强强联合&#xff0c;推出了定制款“格力晶弘303升变频风冷多门冰箱”。它不仅是业界首款全部由人工智能&#xff08;AI&#xff09;进行…