力扣周赛第245期(下)

289 阅读2分钟

这是我参与8月更文挑战的第23天,活动详情查看:8月更文挑战

1970. 你能穿过矩阵的最后一天

截屏2021-08-23 下午10.27.16.png

思路分析

在假设所有水域都是第一天以前被变出来的,那么这道题就是水域和陆地,水域是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,那么我们可以通过假定结果集的方式,用二分实现一种遍历的效果,就像图中经典的根据稀疏边还是稀疏点来更换遍历方式剪枝一样,当计算复杂的时候,二分的优势也体现了出来。