leetcode1631 最小体力消耗路径

思路1:

最短路问题变种。

实现1:

 1 class Solution
 2 {
 3 public:
 4     const int INF = 0x3f3f3f3f;
 5     const int dx[4] = {0, -1, 0, 1};
 6     const int dy[4] = {1, 0, -1, 0};
 7     int minimumEffortPath(vector<vector<int>>& heights)
 8     {
 9         int n = heights.size(), m = heights[0].size();
10         using pii = pair<int, int>; 
11         priority_queue<pii, vector<pii>, greater<pii>> q;
12         vector<vector<bool>> vis(n, vector<bool>(m, false));
13         vector<vector<int>> res(n, vector<int>(m, INF));
14         q.push(make_pair(0, 0));
15         while (!q.empty())
16         {
17             pii tmp = q.top(); q.pop();
18             int dis = tmp.first, x = tmp.second / m, y = tmp.second % m; 
19             if (vis[x][y]) continue;
20             vis[x][y] = true;
21             res[x][y] = dis;
22             if (x == n - 1 && y == m - 1) break;
23             for (int i = 0; i < 4; i++)
24             {
25                 int nx = x + dx[i], ny = y + dy[i];
26                 if (nx >= 0 && nx < n && ny >= 0 && ny < m && !vis[nx][ny])
27                 {
28                     int tmp_dis = max(dis, abs(heights[x][y] - heights[nx][ny]));
29                     q.push(make_pair(tmp_dis, nx * m + ny));
30                 }
31             }
32         }
33         return res[n - 1][m - 1];
34     }
35 }

思路2:

二分+dfs(或bfs)。

实现2:

 1 class Solution
 2 {
 3 public:
 4     const int INF = 0x3f3f3f3f;
 5     const int dx[4] = {0, -1, 0, 1};
 6     const int dy[4] = {1, 0, -1, 0};
 7     void dfs(int x, int y, vector<vector<int>>& h, int threshold, vector<vector<bool>>& vis)
 8     {
 9         vis[x][y] = true;
10         int n = h.size(), m = h[0].size();
11         for (int i = 0; i < 4; i++)
12         {
13             int nx = x + dx[i], ny = y + dy[i];
14             if (nx < 0 || nx >= n || ny < 0 || ny >= m) continue;
15             int gap = abs(h[x][y] - h[nx][ny]);
16             if (gap > threshold || vis[nx][ny]) continue;
17             dfs(nx, ny, h, threshold, vis);
18         }
19     }
20     bool check(vector<vector<int>>& h, int threshold)
21     {
22         int n = h.size(), m = h[0].size();
23         vector<vector<bool>> vis(n, vector<bool>(m, false));
24         dfs(0, 0, h, threshold, vis);
25         return vis[n - 1][m - 1];
26     }
27     int minimumEffortPath(vector<vector<int>>& heights)
28     {
29         int l = 0, r = 1e6, res = INF;
30         while (l <= r)
31         {
32             int mid = l + r >> 1;
33             if (check(heights, mid))
34             {
35                 res = mid;
36                 r = mid - 1;
37             }
38             else l = mid + 1;
39         }
40         return res;
41     }
42 }

思路3:

并查集。

实现3:

 1 class Solution
 2 {
 3 public:
 4     int find(int x, vector<int>& p)
 5     {
 6         if (p[x] == x) return x;
 7         return p[x] = find(p[x], p);
 8     }
 9     void uni(int x, int y, vector<int>& p)
10     {
11         x = find(x, p), y = find(y, p);
12         if (x != y) p[x] = y;
13     }
14     int minimumEffortPath(vector<vector<int>>& heights)
15     {
16         using tiii = tuple<int, int, int>;
17         int n = heights.size(), m = heights[0].size();
18         vector<int> p(n * m);
19         for (int i = 0; i < n * m; i++) p[i] = i;
20         vector<tiii> v;
21         for (int i = 0; i < n; i++)
22         {
23             for (int j = 0; j < m; j++)
24             {
25                 int id = i * m + j;
26                 if (i + 1 <= n - 1)
27                 {
28                     int nid = (i + 1) * m + j;
29                     int gap = abs(heights[i][j] - heights[i + 1][j]);
30                     v.push_back(make_tuple(gap, id, nid));
31                 } 
32                 if (j + 1 <= m - 1)
33                 {
34                     int nid = i * m + j + 1;
35                     int gap = abs(heights[i][j] - heights[i][j + 1]);
36                     v.push_back(make_tuple(gap, id, nid));
37                 }
38             }
39         }
40         sort(v.begin(), v.end());
41         int i = 0;
42         for ( ; i < v.size(); i++)
43         {
44             int a = find(0, p), b = find(n * m - 1, p);
45             if (a == b) break;
46             int x = get<1>(v[i]), y = get<2>(v[i]);
47             uni(x, y, p);
48         }
49         return i == 0 ? 0 : get<0>(v[i - 1]);
50     }
51 }
原文地址:https://www.cnblogs.com/wangyiming/p/14354682.html