这是我参与8月更文挑战的第23天,活动详情查看:8月更文挑战
1970. 你能穿过矩阵的最后一天
思路分析
在假设所有水域都是第一天以前被变出来的,那么这道题就是水域和陆地,水域是1陆地是0,一道简单的dfs遍历题。
但是由于水域和陆地转换是具有时间维度的规律,因此我们可以将数组设置为第i天变为水域的i和不会形成水域的0,用-1表示已经访问过。
不过由于需要回溯时恢复数组,因此最好还是设计成两份数组,一份表示水域和陆地,一份表示是否访问过。
那这就是一道简单的dfs了。
但是!
题目中提到:请返回只经过陆地格子能从最 上面 一行走到最 下面 一行的 最后一天 。
因此我们并不是计算是否可以通过,而是计算最晚什么时候可以通过,因此我们需要dfs计算每种可能,比较得到从最 上面 一行走到最 下面 一行的 最大值。
作为周赛的第四题,不给他优化剪枝一下未免说不过去,这种顺序的遍历最好的优化方式就是二分了。
二分代码如下:
int low = 1, high = cells.size();
while (low < high) {
int mid = ((low + high) >> 1) + 1;
vector<vector<int>> graph(backup);
for (int j = 0; j < n; ++j) {
if (dfs(graph, 0, j, mid)) {
low = mid;
break;
}
}
if (low != mid) {
high = mid - 1;
}
}
总结:
二分查找作为一个查找算法,其优点是快速的,缺点则是对数据集要求较高。二分查找依赖一个静态有序的数据集。
而这样的数据集要么是题目直接给出(当然这类题也非常简单),更多的场景是作为对结果集的剪枝,比如小明的分数一定是1~100,那么我们可以通过假定结果集的方式,用二分实现一种遍历的效果,就像图中经典的根据稀疏边还是稀疏点来更换遍历方式剪枝一样,当计算复杂的时候,二分的优势也体现了出来。