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;
}
};
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一次一次尝试到可行,每次都合并能走到的点。