LeetCode第212场周赛(2020/10/25)

前两题略

3. 最小体力消耗路径

在这里插入图片描述

参考链接

dijkstra优化

#define INF 0x3f3f3f3f
struct Dist{
    int x,y,z;
    Dist(int _x, int _y, int _z):x(_x), y(_y), z(_z){}
    bool operator < (const Dist& A) const
    {
        return z > A.z;
    } 
};
class Solution {
public:
    int N,M;
    int dx[4] = {1,-1,0,0};
    int dy[4] = {0,0,1,-1};
    vector<vector<int>> dis;
    vector<vector<bool>> vis;
    vector<vector<int>> h;
    int dijkstra(int sx,int sy)
    {
        dis[sx][sy] = 0;
        priority_queue<Dist> que;
        que.emplace(0,0,0);
        while(!que.empty())
        {
            int x = que.top().x;
            int y = que.top().y;
            int z = que.top().z;
            que.pop();
            if(vis[x][y])
                continue;
            vis[x][y] = true;
            dis[x][y] = z;
            for(int i=0;i<4;i++)
            {
                int nx = x+dx[i];
                int ny = y+dy[i];
                if(nx<N&&nx>=0&&ny<M&&ny>=0&&!vis[nx][ny])
                {
                    que.emplace(nx,ny,max(z,abs(h[nx][ny]-h[x][y])));
                }
            }
        }
        return dis[N-1][M-1];
    }
    int minimumEffortPath(vector<vector<int>>& heights) {
        N = heights.size();
        M = heights[0].size();
        h = heights;
        dis = vector<vector<int>>(N,vector<int>(M,INF));
        vis = vector<vector<bool>>(N,vector<bool>(M,false));
        return dijkstra(0,0);

    }
};

二分 + dfs

typedef struct P
{
    int x;
    int y;
}P;
class Solution {
public:
    int dx[4] = {1,-1,0,0};
    int dy[4] = {0,0,1,-1};
    int minimumEffortPath(vector<vector<int>>& heights) {
        int le = 0;
        int ri =  1e6+1;
        int mid = (le+ri)/2;
        int ans = 0x3f3f3f3f;
        int N = heights.size();
        int M = heights[0].size();
        while(le < ri)
        {
            mid = (le+ri)/2;
            queue<P> que;
            que.push({0,0});
            vector<vector<bool>> vis = vector<vector<bool>>(N,vector<bool>(M));
            while(!que.empty())
            {
                int x = que.front().x;
                int y = que.front().y;
                que.pop();
                vis[x][y] = true;
                for(int i=0;i<4;i++)
                {
                    int nx = x+dx[i];
                    int ny = y+dy[i];
                    if(nx>=0&&nx<N&&ny>=0&&ny<M&&!vis[nx][ny]&&abs(heights[x][y]-heights[nx][ny])<=mid)
                    {
                        que.push({nx,ny});
                        vis[nx][ny] = true;
                    }
                }
            }
            if(vis[N-1][M-1])
            {
                ans = mid;
                ri = mid;
            }
            else{
                le = mid+1;
            }
        } 
        return ans;
    }
};

并查集

struct Edge
{
    int from, to, dis;
    bool operator < (const Edge& e) const
    {
        return dis < e.dis;
    }
};
vector<int> fa;
    int Find(int x)
    {
        return x == fa[x] ? x : fa[x] = Find(fa[x]);
    }
    void Union(int x, int y)
    {
        int fx = Find(x);
        int fy = Find(y);
        if(fx>fy)
            fa[fx] = fy;
        else fa[fy] = fx;
    }
    void init(int N)
    {
        fa = vector<int>(N);
        for(int i=0;i<N;i++)
            fa[i] = i;
    }
class Solution {
public:
    int minimumEffortPath(vector<vector<int>>& heights) {
        int N = heights.size();
        int M = heights[0].size();
        vector<Edge> edges;
        for(int i=0;i<N;i++)
        {
            for(int j=0;j<M;j++)
            {
                int id = i * M + j;
                //上下边
                if(i > 0)
                    edges.push_back({id-M,id,abs(heights[i][j]-heights[i-1][j])});
                //左右边
                if(j > 0)
                     edges.push_back({id-1,id,abs(heights[i][j]-heights[i][j-1])});
            }
        }
        sort(edges.begin(),edges.end());
        init(N*M);
        
        for(auto edge : edges)
        {
            Union(edge.from, edge.to);
            if(Find(N*M-1)==0)
                return edge.dis;
        }
        return 0;
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值