【BFS】 773. 滑动谜题

2024-02-14 13:12
文章标签 bfs 谜题 滑动 773

本文主要是介绍【BFS】 773. 滑动谜题,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

773. 滑动谜题

解题思路

  • 首先定义了一个 slidingPuzzle 方法,接收一个二维数组 board 作为参数,表示初始的拼图板状态,然后返回一个整数表示移动到目标状态所需的最小步数。

  • 初始化了一个二维数组 neighbor,用于记录每个数字在一维字符串中的相邻索引,这是为了在移动数字时判断合法性。

  • 创建了一个队列 q 和一个哈希集 visited。队列用于广度优先搜索(BFS)时存储待处理的拼图板状态,哈希集用于记录已经访问过的拼图板状态,避免重复访问。

  • 将初始的二维数组转换成一维字符串,并将其作为起始状态加入队列,并标记为已访问。

  • 在一个循环中,不断从队列中取出拼图板状态进行处理,直到队列为空。在每一步中,先判断当前状态是否为目标状态,若是则返回步数。

  • 若当前状态不是目标状态,则遍历每个数字的相邻索引,尝试将数字0与相邻数字交换位置,生成新的拼图板状态。

  • 如果新状态未被访问过,则将其加入队列,并标记为已访问。

  • 最后返回 -1,表示无法达到目标状态。

class Solution {public int slidingPuzzle(int[][] board) {int m = 2;int n = 3;StringBuilder sb = new StringBuilder();String target = "123450";// 将2 x 3数组转换为字符串 作为BFS的起点局面for(int i = 0; i < board.length; i++){for(int j = 0; j < board[0].length; j++){sb.append(board[i][j]);}}String start = sb.toString();// 记录一维字符串的相邻索引int[][] neighbor = new int[][]{{1,3},{0,4,2},{1,5},{0,4},{3,1,5},{4,2}};Queue<String> q = new LinkedList<>();// 双向链表模拟队列HashSet<String> visited = new HashSet<>();// 从起点开始搜索q.offer(start);visited.add(start);// 标记已经访问了int step = 0;while(!q.isEmpty()){int sz = q.size();for(int i = 0; i < sz; i++){String cur = q.poll();// 判断是否到达目标局面if(target.equals(cur)){return step;}// 没有到达 搜索下一种字符串局面 然后入队// 通过计算索引0 的周围索引 然后移动 判断新的字符串是否出现过// 新的字符串没有出现过  直接入队// 找到数字0的索引int id = 0;for(;cur.charAt(id) != '0'; id++);// 将数字0和相邻的数字交换位置for(int adj: neighbor[id]){// 遍历数字0 的相邻数字的索引String new_board = swap(cur.toCharArray(),adj,id);// 判断新的字符串是否已经出现过if(!visited.contains(new_board)){// 如果没有出现过  直接入队q.offer(new_board);visited.add(new_board);// 标记已经出现过}}}step++;}return -1;// 没找到 直接-1}// 交换一个字符串的两个字符private String swap(char[] chars,int i,int j){char temp = chars[i];chars[i] = chars[j];chars[j] = temp;return new String(chars);}
}

这篇关于【BFS】 773. 滑动谜题的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/708601

相关文章

基于Redis有序集合实现滑动窗口限流的步骤

《基于Redis有序集合实现滑动窗口限流的步骤》滑动窗口算法是一种基于时间窗口的限流算法,通过动态地滑动窗口,可以动态调整限流的速率,Redis有序集合可以用来实现滑动窗口限流,本文介绍基于Redis... 滑动窗口算法是一种基于时间窗口的限流算法,它将时间划分为若干个固定大小的窗口,每个窗口内记录了该时间

hdu1254(嵌套bfs,两次bfs)

/*第一次做这种题感觉很有压力,思路还是有点混乱,总是wa,改了好多次才ac的思路:把箱子的移动当做第一层bfs,队列节点要用到当前箱子坐标(x,y),走的次数step,当前人的weizhi(man_x,man_y),要判断人能否将箱子推到某点时要嵌套第二层bfs(人的移动);代码如下:

poj 2195 bfs+有流量限制的最小费用流

题意: 给一张n * m(100 * 100)的图,图中” . " 代表空地, “ M ” 代表人, “ H ” 代表家。 现在,要你安排每个人从他所在的地方移动到家里,每移动一格的消耗是1,求最小的消耗。 人可以移动到家的那一格但是不进去。 解析: 先用bfs搞出每个M与每个H的距离。 然后就是网络流的建图过程了,先抽象出源点s和汇点t。 令源点与每个人相连,容量为1,费用为

POJ 3057 最大二分匹配+bfs + 二分

SampleInput35 5XXDXXX...XD...XX...DXXXXX5 12XXXXXXXXXXXXX..........DX.XXXXXXXXXXX..........XXXXXXXXXXXXX5 5XDXXXX.X.DXX.XXD.X.XXXXDXSampleOutput321impossible

深度优先(DFS)和广度优先(BFS)——算法

深度优先 深度优先搜索算法(英语:Depth-First-Search,DFS)是一种用于遍历或搜索树或图的算法。 沿着树的深度遍历树的节点,尽可能深的搜索树的分支,当节点v的所在边都己被探寻过,搜索将回溯到发现节点v的那条边的起始节点。这一过程一直进行到已发现从源节点可达的所有节点为止。如果还存在未被发现的节点,则选择其中一个作为源节点并重复以上过程,整个进程反复进行直到所有节点都被访

专题二_滑动窗口_算法专题详细总结

目录 滑动窗口,引入: 滑动窗口,本质:就是同向双指针; 1.⻓度最⼩的⼦数组(medium) 1.解析:给我们一个数组nums,要我们找出最小子数组的和==target,首先想到的就是暴力解法 1)暴力: 2)优化,滑动窗口: 1.进窗口 2.出窗口 3.更新值 2.⽆重复字符的最⻓⼦串(medium) 1)仍然是暴力解法: 2)优化: 进窗口:hash[s[rig

hot100刷题第1-9题,三个专题哈希,双指针,滑动窗口

求满足条件的子数组,一般是前缀和、滑动窗口,经常结合哈希表; 区间操作元素,一般是前缀和、差分数组 数组有序,更大概率会用到二分搜索 目前已经掌握一些基本套路,重零刷起leetcode hot 100, 套路题按套路来,非套路题适当参考gpt解法。 一、梦开始的地方, 两数之和 class Solution:#注意要返回的是数组下标def twoSum(self, nums: Lis

双头BFS

牛客月赛100 D题,过了80%数据,调了一下午。。。烦死了。。。 还是没调试出来,别人的代码用5维的距离的更新有滞后性,要在遍历之前要去重。。。 #include<bits/stdc++.h>using namespace std;const int N=2e3+10;char g[N][N];int dis[N][N],d1[N][N];int n,m,sx,sy;int dx

Knight Moves -uva 简单的BFS遍历

昨天刚学了BFS的遍历,在uva上找了个题敲了出来,感觉还不错,最近敲代码挺有手感的,希望这种状态保持下去 #include<iostream>#include<stdio.h>#include<stdlib.h>#include<string.h>#define MAX_SIZE 10 + 5#define LEN 100 + 10using namespace std;in

【CF】D. Arthur and Walls(BFS + 贪心)

D题 解题思路就是每次检查2X2的方格里是否只有一个‘*’,如果有的话这个*就需要变成‘.’,利用BFS进行遍历,入队的要求是这个点为. 一开始将所有的'.'全部加入队列,如果碰到一个'*'变成'.'就入队,判断的时候从4个方向就行判断 题目链接:http://codeforces.com/contest/525/problem/D #include<cstdio>#include<