算法课堂——时光倒流二(栈)
这是我参与2022首次更文挑战的第8天,活动详情查看:2022首次更文挑战」。
上一节算法课堂我们学习了栈的基本概念,并且将栈和队列做了比较,并且研究了如何用队列来实现栈。不过我们还没有见识到栈如何进行时光倒流操作的,今天我们用一道稍微复杂且有趣的题目带大家领略一下“回溯”的风采
一、迷宫问题
相信大家或多或少知道什么是迷宫问题。
是不是有点眼花缭乱?没错,迷宫嘛,要的就是让你晕头转向,但是学习了今天算法课堂,你就会知道如何以计算机的思维解决这中看似复杂的问题。
首先如果你来解的话,你会怎么去走这个迷宫呢?上面的迷宫可能有点复杂,我们举一个比较简单的例子:
这个迷宫怎么样?是不是感觉能解?
那么你是怎么解的呢?我们用一个动画演示一下(第一次有动画,哈哈)
没错,我们解迷宫题用到的思想就是回溯,走到不能走的地方,我们回头,往另外的可能性走,所以回溯思想也叫做试错。
那么计算机呢?其实,计算机并不比我们人要聪明,它只是能准确得记住自己所走的路,而且能一直走,不会累,那么计算机究竟是怎样记住它走的每一步呢?并且如何准确地回到之前走的路呢?这就要用到我们的主角--栈了。
上节课我们分析了,由于栈的先入后出的特性,我们把栈顶的元素出栈,就能回到我们上一步,所以我们就运用栈的特性,来辅助我们完成迷宫。
首先我们用二维数组来表示我们的迷宫,我们规定,蓝色(不能走的地方),我们用0表示,黄色(能走的地方)我们用1表示,于是上面的迷宫用我们的二维数组表示出来就是:
[[1,1,1,0,0,0].
[0,1,0,0,1,0],
[0,1,0,1,1,0],
[0,1,0,1,0,0],
[0,1,1,1,1,1],
[0,1,0,0,0,0]]
我们的起点是(0,0),如果我们写一个方法能够正确的找到(4,5),也就是出口,就代表我们走出迷宫了。
我们思考下,首先我们在(0,0),先将(0,0)入栈。
接下来我们可以选择往上下左右四个方向走,首先往左,不可能,往上,也不可能,往下是(1,0)由于坐标(1,0)的值是0,所以也不能走,我们只能往右走到(0,1)。我们将(0,1)入栈。
接下来根据我们的规则,我们既可以往右走,也可以往下走,我们不知道往哪走,我们先尝试一下,我们往右走,将(0,2)入栈。
这个时候呢?我们往哪走?我们发现没地方可以走了,这个时候,我们呢就要时光倒流了哦。 我们发现无路可走的时候我们就往回走,并且把移除的坐标的路堵死。也就是把出栈的坐标的值改成0。 此时,我们将(0,2)出栈。
并将迷宫改成:
[[1,1,0,0,0,0].
[0,1,0,0,1,0],
[0,1,0,1,1,0],
[0,1,0,1,0,0],
[0,1,1,1,1,1],
[0,1,0,0,0,0]]
也就是这样:
这个时候我们回到了(0,1),我们只能往下走了。所以我们将(1,1)入栈:
接下来就是将(2,1)、(3,1)、(4,1)入栈。
这个时候,我们又到了选择的时候了。如果我们又没选对,我们往下走,将(5,1)入栈。到了(5,1)我们发现我们又没地方走了,所以我们将(5,1)出栈,并且将(5,1)的值变成0。此时我们又回到了(4,1)。迷宫变成了这样:
所以说我们的回溯算法就是不断的试错,回溯,试错,回溯。。。。。直到我们找到正确的道路。
好了,到这里大部分同学对解迷宫的思想应该有了了解,思想明白了,代码也就很简单了。有能力的小伙伴可以将算法写在评论区。我会和你一起讨论哦。
明天更新文章时,我会将我的答案更新在本节算法课堂的评论区。欢迎大家指正。
不知不觉我们已经学习了,数组、链表、队列、栈四种数据结构,接下来,我将和大家一起学习我们面试中最常见也最方便考察我们计算机基础的数据结构之一:树,如果你有兴趣,请关注我的算法课堂专栏,下一节: