• 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 }
  • 相关阅读:
    你真的会用Android的Dialog吗?由一个Exception想到的
    请慎用java的File#renameTo(File)方法
    Android核心分析(16)Android电话系统概述篇
    java.lang.UnsupportedOperationException
    fastboot 刷新 system.img 出现 data too large 错误
    Android是什么 之三手机之硬件形态
    快速重建system.img
    Android 核心分析 之五 基本空间划分
    Android核心分析之四 手机的软件形态
    Android核心分析(15)Android输入系统之输入路径详解k
  • 原文地址:https://www.cnblogs.com/wangyiming/p/14354682.html
Copyright © 2020-2023  润新知