美文网首页
1631. 最小体力消耗路径

1631. 最小体力消耗路径

作者: 来到了没有知识的荒原 | 来源:发表于2020-11-02 16:06 被阅读0次

1631. 最小体力消耗路径

二分+搜索

bfs 搜索验证答案是否合法

class Solution {
public:
    int dx[4] = {-1, 0, 1, 0}, dy[4] = {0, 1, 0, -1};

    int minimumEffortPath(vector<vector<int>> &heights) {
        int n = heights.size(), m = heights[0].size();
        int left = 0, right = 1e6, res;

        while (left <= right) {
            int mid = left + right >> 1;
            queue<pair<int, int>> q;
            vector<bool> vis(n * m);
            q.emplace(0, 0);
            while (!q.empty()) {
                auto t = q.front();
                int x = t.first, y = t.second;
                q.pop();
                if (vis[x * m + y])continue;
                vis[x * m + y] = true;
                if (vis[n * m - 1])break;

                for (int i = 0; i < 4; i++) {
                    int a = x + dx[i], b = y + dy[i];
                    if (a >= 0 && a < n && b >= 0 && b < m && !vis[a * m + b] &&
                        abs(heights[a][b] - heights[x][y]) <= mid) {
                        q.emplace(a, b);
                    }
                }
            }

            if (vis[n * m - 1]) {
                res = mid;
                right = mid - 1;
            } else {
                left = mid + 1;
            }
        }
        return res;
    }
};

dijkstra

还是堆优化版的dijkstra

struct Edge {
    int x, y, z;

    bool operator<(const Edge &e) const {
        return z > e.z;
    }
};

class Solution {
public:
    int dx[4] = {-1, 0, 1, 0}, dy[4] = {0, 1, 0, -1};

    int minimumEffortPath(vector<vector<int>> &heights) {
        int n = heights.size(), m = heights[0].size();
        vector<bool> vis(n * m);
        vector<int> dist(n * m);

        priority_queue<Edge> q;
        q.push({0, 0, 0});
        while (!q.empty()) {
            auto[x, y, z]=q.top();
            q.pop();
            if (vis[x * m + y])continue;
            vis[x * m + y] = true;
            dist[x * m + y] = z;
            for (int i = 0; i < 4; i++) {
                int a = x + dx[i], b = y + dy[i];
                if (a >= 0 && a < n && b >= 0 && b < m && !vis[a * m + b]) {
                    q.push({a, b, max(z, abs(heights[x][y] - heights[a][b]))});
                }
            }
        }

        return dist[m * n - 1];
    }
};

并查集

「并查集」:我们可以将所有边按照长度进行排序并依次添加进并查集,直到左上角和右下角连通为止。

struct Edge {
    int x, y, z;

    bool operator<(Edge &e) {
        return z < e.z;
    }
};

class Solution {
public:
    vector<int> p;

    int find(int x) {
        if (p[x] != x)p[x] = find(p[x]);
        return p[x];
    }

    void merge(int a, int b) {
        p[find(a)] = find(b);
    }

    int minimumEffortPath(vector <vector<int>> &heights) {
        int n = heights.size(), m = heights[0].size();
        p.resize(n * m);
        for (int i = 0; i < p.size(); i++)p[i] = i;
        vector <Edge> edges;

        for (int i = 0; i < n; i++) {
            for (int j = 0; j < m; j++) {
                int id = i * m + j;
                if (i) {
                    edges.push_back({id - m, id, abs(heights[i][j] - heights[i - 1][j])});
                }
                if (j) {
                    edges.push_back({id - 1, id, abs(heights[i][j] - heights[i][j - 1])});
                }
            }
        }

        sort(edges.begin(), edges.end());

        for (auto e:edges) {
            merge(e.x, e.y);
            if (find(0) == find(n * m - 1)) {
                return e.z;
            }
        }

        return 0;
    }
};

相关文章

  • 1631. 最小体力消耗路径

    1631. 最小体力消耗路径[https://leetcode-cn.com/problems/path-with...

  • 1631最小体力消耗路径(二分+DFS/BFS,并查集)

    又是一道题一个上午 主要是两种方法 第一种是用二分法+DFS/BFS, 第二种是并查集

  • 减肥第一定律解读(三)

    路径一:增强体力活动中的消耗,方法即结论,简单却不高效。 平心而论,相对其他的路径,这一条最是“实在”,你看到的既...

  • 深度工作

    大部分人们喜欢做简单没有压力的工作,习惯选择脑力消耗最弱,耗费体力最小的工作是因为潜意识缺乏明确的工作动机,无形当...

  • 图的最短路径算法(Dijkstra和Floyd)

    最短路径和最小生成树的区别:最短路径解决的是如何求解各顶点之间的路径权值和最小的问题。最小生成树是保证图的所有路径...

  • Exploiting Caching and multicast

    “Proactive Retention Aware Caching”系列, 同为最小消耗。这里的消耗分为SBS存...

  • 算法2

    一.计算两个点的最小路径(Dijkstra算法)二.计算图上任意点到其他点的最小路径(Floyd算法)三.最小生成...

  • 算法

    一.计算两个点的最小路径(Dijkstra算法)二.计算图上任意点到其他点的最小路径(Floyd算法)三.最小生成...

  • 小学问(第11~20期)

    11)黄执中:认清风险劳动 四种劳动性质:脑力劳动:老师(消耗脑力)体力劳动:农夫(消耗体力)情绪劳动:客服人员(...

  • Graph-一般算法

    和图相关的算法有:最小生成子树,最短路径,拓扑排序。 这里仅介绍最小生成树和最短路径,拓扑排序暂时省略。 最小生成...

网友评论

      本文标题:1631. 最小体力消耗路径

      本文链接:https://www.haomeiwen.com/subject/bvcuvktx.html