蓝桥杯--BFS-八数码问题(算法笔记8)

    题目中输入初始状态和目标状态,返回最少的移动步数。

这与迷宫问题的最短路劲有些许相似,但这里更多的是一种状态的思考,本题涉及到“康托展开”这个特殊的哈希函数。

    由于BFS一般用队列来实现,其实看到这个题目,可以很容易看到几个状态。假设空白格子中数字为0,那么按照搜索的思路,肯定是四个方向搜索,那么0的位置可以向左上右下四个方向移动,移动过后的状态又是一个新的状态。接着从新的状态继续发散,这不就是BFS队列方法的的入队出队嘛,和上一讲中的BFS迷宫问题2的思路是一样的,这样一想,似乎并不难,且也就那样。

    但是,思路有了不代表能做对,因为AC还要考虑时间复杂度,空间复杂度问题,不过一般空间复杂度都没太大的问题。那么为什么这里说不能做对?这里参考书上的图

图中画红色三角形的两个状态明显是重复的状态,也就是说这个状态已经被搜索过了。那么从搜索过的状态再进行延伸,就会有很多重复的搜索,浪费了大量的时间。那么这题的关键就是如何去重,去重的方式可以参考爬楼梯问题的三部曲(普通递归,记忆性递归,动态规划-递推),也就是标记走过的点,这里就是标记走过的状态。

那么这里题目是一个3*3的数组,类比迷宫问题,发现我们可以用坐标的方式去做。但此时又有问题,坐标标记状态?这显然不可行,因为随着0的移动,这个棋盘的状态是在改变的,而迷宫问题中,迷宫是固定的,点的标记只是为了回溯的时候方便(避免搜索重复)。而且就算能按照之前的方式来做,那么这个去重的过程,要涉及到的状态n!×n!是否又太过于复杂?

    这里两个点要考虑:①状态怎么表示?②能不能用坐标做?③去重到底怎么去重?

答案:数组表示,能,用康托展开。

    先说状态怎么表示:状态只需要用一维数组存放即可,数组的大小就是n×n,其实这就是将从第二行开始的每一行直接放在第一行后面进行存放。

    再说坐标:按照一维数组的存放状态,那么每n个就可以确定一行,列的确定只需要除n。举个例子:假设在数组{0,1,2,3,4,5,6,7,8}中,我想知道5在3*3的格子中处于哪个位置(以左上角为(0,0)),那么6/3就是行x,6%3的就是列y,这里的6是指5在数组中第六个。这里的解释和书上代码有些不同,具体实现我还没试过。

    最后是去重的康托展开:

康托展开的时间复杂度分析:

 

最后是代码:

 

最后提醒:

    

 

    

 

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

澄澈i

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值