**Leetcode 778. Swim in Rising Water

https://leetcode.com/problems/swim-in-rising-water/description/

感觉优先队列的搜索才是正解

证明的话,就是当通过优先队列bfs到解的时候,所有小于当前解的路径都试过了。

struct Node {
    int x, y;
    int v;
    Node(int x, int y, int v) :x(x), y(y), v(v){}
    bool operator < (const Node &t) const {
        return v > t.v;
    }
};

int yy[]={-1,1,0,0};
int xx[]={0,0,-1, 1};

class Solution {
public:
    int swimInWater(vector>& grid) {
        if (grid.size() == 0) return 0;
        priority_queue q;
        int n = grid.size(), m = grid[0].size();
        q.push(Node(0,0, grid[0][0]));
        set< pair > visit;
        while (!q.empty()) {
            Node tp = q.top();
            q.pop();
            if (tp.x == n-1 && tp.y == m-1) {
                return tp.v;
            }
            for (int i = 0; i < 4; i++) {
                int x = tp.x + xx[i];
                int y = tp.y + yy[i];
                pairpos = make_pair(x, y);
                if  (x >= 0 && x < grid.size()  && y >=0 && y < grid[0].size() && visit.find(pos) == visit.end() ) {
                    visit.insert( pos );
                    q.push( Node(x, y, max(tp.v, grid[x][y]) ));
                }
            }
        }
        return -1;
    }
};

另解: 二分答案+dfs

int yy[]={-1,1,0,0};
int xx[]={0,0,-1, 1};

class Solution {
public:
    
    bool dfs(int x_, int y_, vector >& grid, set< pair >&visit, int v) {
        if (grid[x_][y_] > v) return false;
        if (x_ == grid.size() - 1 && y_ == grid[0].size() - 1) {
            return true;
        }
        bool ret = false;
        for (int i = 0; i < 4; i++) {
                int x = x_ + xx[i];
                int y = y_ + yy[i];
                pairpos = make_pair(x, y);
                if  (x >= 0 && x < grid.size()  && y >=0 && y < grid[0].size() && visit.find(pos) == visit.end() && grid[x][y] <= v ) {
                    visit.insert( pos );
                    ret |= dfs(x, y, grid, visit, v);
                    if (ret) return true;
                    // visit.erase( pos );
                }
            }
        return ret;
    }
    
    int swimInWater(vector>& grid) {
        if(grid.size() == 0) return 0;
        set< pair >visit;
        int n = grid.size();
        int m = grid[0].size();
        int mx = 0;
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < m; j++) {
                mx = max( mx, grid[i][j] );
            }
        }
        int l = 0, r = mx+1;
        while (l<=r) {
            int mid = (l+r)/2;
            if (dfs(0, 0, grid, visit, mid)) {
                r = mid - 1;
            } else {
                l = mid + 1;
            }
            visit.clear();
        }
        return l;
    }
};


还有一个解,并查集 https://discuss.leetcode.com/topic/119515/kotlin-solution-using-union-set-with-the-time-complexity-of-o-n-2

其实思路也是差不多,就是从ans=0一次一次尝试到可行,每次都合并能走到的点。




你可能感兴趣的:(搜索-DFS,LeetCode题解)