最近笔试遇到了这样一道题
有一个n*n大小的棋盘,棋盘上有一些棋子,这些棋子没有连成5个的。现在你手中有一枚棋子,请你找出所有落子后能连成五个的点。
1.解题思路
这种题乍一看应该会想到算法题中的岛屿数量这道题,并一股脑的用广度优先搜索,那这就给自己挖坑了。五子棋是直线或者斜线连5个才算赢,广度优先会导致搜索出来的棋子奇形怪状。首先我们确定解题的大方向是用递归,但是在细节上还要考量一下。
2.递归变型
首先我们想象自己是电脑,如果给你一个点,你怎么判断这个点出发是否能连成5个呢?我是这样想的“从这个点向上下左右和斜着的上下左右去找,如果某一条线能连成5个那这个点就是五子中的一子”。有了这个想法,递归的大致模样也就出来了。但是这样的递归算深度优先还是广度优先呢?说深度可以,因为他从点出发,沿着某个方向一直找,直到不能满足连成5个。说广度也可以,因为他将点的所有方向放入了递归,这也可以看做是广度优先。其实非要定义他是广度还是深度没有太大意义,算法就是一个架子嘛,你去对应的场景中合理的利用他就好了,管他是什么名词呢。我们就暂且理解为深度和广度的结合,或者是方向锁定的广度优先。
3.落子生根
递归中难免会出现中间断掉的点,解决递归中这些不连续的点,所以要“落子”,还要判断手中的棋子最终的落点,所以要“生根”。当手中有棋子时,遇到空点就下,若果最终能连成五个,那落子点就会要生根,代表这个点落子后一定会出现5子。