小岛问题汇总

在做搜索题时,做到了三道小岛问题,比较类似。虽然都是比较基础的题目,还是写一篇解题报告总结三题的思路和方法,题目链接如下:

1.第九届蓝桥杯江苏省赛C语言a组第8题全球变暖
2.hihocoder第156周岛屿
3.LeetCode 934 Shortest Bridge
下面分别介绍我对三道题的思路和做法

一.全球变暖
这一题思路很明确:搜索找到小岛,而且实现也不复杂。不过这一题的坑点也在这。说白了,这一题只有这个坑点需要注意,本质上是道水题。很多人的第一想法就是搜索一遍找多少个小岛,再搜一遍找被淹后还剩多少个小岛,然后做差即为被淹没的小岛数。不过这是错误的。反例如图:

小岛问题汇总_第1张图片
反例一(被淹前)


小岛问题汇总_第2张图片
反例一(被淹后)

如图可见,被淹前有一个小岛,被淹后为两个小岛,做差为负数,显然,这种思路是错误的。其实发现这个坑后,就很简单了。只要搜一遍,看一个小岛的陆地中有没有四面都不临海的,如果没有,这个小岛就会被淹没。关键代码如下:

搜索题经典做法,四个方向
小岛问题汇总_第3张图片

搜索代码

二.hiho156
这题的一二问是水题,最基本的搜索题。第三问其实也没有特别好的做法,要记录每个小岛每个点的坐标(暴力。。。)最简单的就是用一个二维vector记录。值得注意的是因为遍历输入的二维数组的时候都是按行遍历或者按列遍历,搜索时也都是按一块陆地上下左右的某个排列进行,所以如果两个小岛的形状相同,那么在搜索后得到的一系列坐标也都是对应的,不用再进行排序等操作。不过题解使用了vector >存储每块陆地坐标,更简化了代码。关键代码如下:(只贴了第三问代码)

小岛问题汇总_第4张图片
该题数据结构


小岛问题汇总_第5张图片
搜索部分


小岛问题汇总_第6张图片
判断小岛的形状

三.LeetCode 934
这一题用到了边界广搜的算法(floodfill算法)。以其中一个小岛为基础,每次把这个小岛扩充一圈,直到和另一个小岛相邻。我不断用O(n^2)的时间遍历数组,每次遍历寻找处在要扩充的一圈上的点,上色。当然也可以使用队列,不断入队出队。关键代码如下:

小岛问题汇总_第7张图片
判断坐标是否越界


小岛问题汇总_第8张图片
初始搜索给两个小岛上色


小岛问题汇总_第9张图片
边界扩充

时间复杂度分析:
每次边界扩充增加的点数是一个等差数列,因此迭代O(n)次可以填充O(n^2)个点,而最多有O(n^2)个点为海洋,所以最多迭代O(n)次可得到答案,每次迭代需要O(n^2)时间遍历数组,因此总时间为O(n^3)。

以上即为三道小岛问题的汇总,其实这种不太难的搜索题就是考手速和熟练度,还有思考问题的严谨性。只要小心题目中的坑,手够快,这类题目都会迎刃而解。

你可能感兴趣的:(小岛问题汇总)