• 剑指offer专项突击版第38天


    剑指 Offer II 111. 计算除法

    BFS

    1. 仔细思考发现,他们除法运算的关系就是图的数据结构, a / b a / b a/b 就相当于与从 a a a 走到 b b b 的边权乘积,边权就是他们的倍数关系 v a l u e s values values
    2. 为了更高效的构造邻接表,使用哈希表,将变量对映射成整数,然后对于每个 q u e r y query query 只需 B F S BFS BFS 从起点走到终点即可。
    class Solution {
    public:
        typedef pair<int,double> PID;
        unordered_map<string,int> um;
    
        double bfs(string &a, string &b, vector<vector<PID>> &edges) {
            if(a == b) return 1;
            int st = um[a], ed = um[b];
            queue<int> que; que.emplace(st);
            vector<double> dis(um.size(),-1);
            dis[st] = 1;
            while(que.size()) {
                auto u = que.front(); que.pop();
                for(auto &[v,val]: edges[u]) {
                    if(dis[v] == -1) {
                        dis[v] = dis[u] * val;
                        if(v == ed) return dis[v];
                        que.emplace(v);
                    }
                }
            }
            return -1;
        }
    
        vector<double> calcEquation(vector<vector<string>>& equations, vector<double>& values, vector<vector<string>>& queries) {
            int idx = 0;
            for(int i = 0; i < equations.size(); i++) { //将变量哈希成整数
                if(!um.count(equations[i][0])) um[equations[i][0]] = idx++;
                if(!um.count(equations[i][1])) um[equations[i][1]] = idx++; 
            }
            vector<vector<PID>> edges(um.size());
            for(int i = 0; i < equations.size(); i++) { //构造邻接表
                auto &x = equations[i][0], &y = equations[i][1];
                int u = um[x], v = um[y];
                edges[u].emplace_back(v, values[i]);
                edges[v].emplace_back(u, 1/values[i]); //反方向就是倒数
            }
            vector<double> res;
            for(auto query: queries) {
                auto &a = query[0], &b = query[1];
                if(!um.count(a) || !um.count(b)) {
                    res.emplace_back(-1);
                } else {
                    res.emplace_back(bfs(a,b,edges)); //bfs获得a到b路径上的乘积
                }
            }
            return res;
        }
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49

    剑指 Offer II 112. 最长递增路径

    记忆化搜索

    比较简单就不赘述了。

    class Solution {
    public:
        int ne[4][2] = {{-1,0},{0,-1},{1,0},{0,1}};
        int n, m;
        int dfs(int x,int y, vector<vector<int>> &matrix, vector<vector<int>> &f) {
            if(f[x][y]) return f[x][y];
            f[x][y]++;
            for(int i = 0; i < 4; i++) {
                int tx = x + ne[i][0];
                int ty = y + ne[i][1];
                if(tx < 0 || tx >= n || ty < 0 || ty >= m) continue;
                if(matrix[x][y] < matrix[tx][ty]) {
                    f[x][y] = max(f[x][y], dfs(tx,ty,matrix,f) + 1);
                }
            }
            return f[x][y];
        }
        int longestIncreasingPath(vector<vector<int>>& matrix) {
            n = matrix.size(), m = matrix[0].size();
            vector<vector<int>> f(n, vector<int>(m,0));
            int res = 0;
            for(int i = 0; i < n; i++)
                for(int j = 0; j < m; j++)
                    res = max(res, dfs(i,j,matrix,f));
            return res;
        }
    
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28

    拓扑排序(BFS)
    将所有元素小的指向大的这就生成了有向图,然后拓扑排序一下,然后这里拓扑排序的层数就是答案,也就是最长的升序序列。

    class Solution {
    public:
        static constexpr int dirs[4][2] = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}};
        int rows, columns;
    
        int longestIncreasingPath(vector< vector<int> > &matrix) {
            if (matrix.size() == 0 || matrix[0].size() == 0) {
                return 0;
            }
            rows = matrix.size();
            columns = matrix[0].size();
            auto outdegrees = vector< vector<int> > (rows, vector <int> (columns));
            for (int i = 0; i < rows; ++i) {
                for (int j = 0; j < columns; ++j) {
                    for (int k = 0; k < 4; ++k) {
                        int newRow = i + dirs[k][0], newColumn = j + dirs[k][1];
                        if (newRow >= 0 && newRow < rows && newColumn >= 0 && newColumn < columns && matrix[newRow][newColumn] > matrix[i][j]) {
                            ++outdegrees[i][j];
                        }
                    }
                }
            }
            queue < pair<int, int> > q;
            for (int i = 0; i < rows; ++i) {
                for (int j = 0; j < columns; ++j) {
                    if (outdegrees[i][j] == 0) {
                        q.push({i, j});
                    }
                }
            }
            int ans = 0;
            while (!q.empty()) {
                ++ans;
                int size = q.size();
                for (int i = 0; i < size; ++i) {
                    auto cell = q.front(); q.pop();
                    int row = cell.first, column = cell.second;
                    for (int k = 0; k < 4; ++k) {
                        int newRow = row + dirs[k][0], newColumn = column + dirs[k][1];
                        if (newRow >= 0 && newRow < rows && newColumn >= 0 && newColumn < columns && matrix[newRow][newColumn] < matrix[row][column]) {
                            --outdegrees[newRow][newColumn];
                            if (outdegrees[newRow][newColumn] == 0) {
                                q.push({newRow, newColumn});
                            }
                        }
                    }
                }
            }
            return ans;
        }
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51

    剑指 Offer II 113. 课程顺序

    简单的拓扑排序

    1. 首先构造课程的拓扑图,将所有需要先完成的课程指向想要学习的课程。
    2. 将所有入度为0的都加入队列中,然后 b f s bfs bfs 依次弹出所有的点,这个顺序就是答案了。
    class Solution {
    public:
        vector<int> findOrder(int numCourses, vector<vector<int>>& prerequisites) {
            int n = prerequisites.size();
            vector<int> res;
            if(n == 0) {
                for(int i = 0; i < numCourses; i++) res.emplace_back(i);
                return res;
            }
            vector<vector<int>> adj(numCourses);
            vector<int> in(numCourses);
            for(int i = 0; i < n; i++) {
                int &u = prerequisites[i][1], &v = prerequisites[i][0]; 
                adj[u].emplace_back(v);
                in[v]++;
            }
            
            queue<int> que;
            for(int i = 0; i < numCourses; i++)
                if(in[i] == 0) que.emplace(i);
    
            while(que.size()) {
                int u = que.front(); que.pop();
                res.emplace_back(u);
                for(int v: adj[u]) {
                    in[v]--;
                    if(in[v] == 0) que.emplace(v);
                }
            }
            return res.size() < numCourses? vector<int>{}: res;
        }
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
  • 相关阅读:
    【拥有新时代的通信协议,引领云原生迈向更高的舞台】解密Dubbo3是如何从微服务升华到云原生领域
    学习笔记-协议
    JAVA微服务快速开发平台的功能特点
    处理器 Handler 详解
    API接口安全设计
    《Redis设计与实现》笔记
    VScode创建ROS项目 ROS集成开发环境
    九、GC收集日志
    【小程序】微信小程序设置globalData全局数据
    GBASE 8A v953报错集锦45--orato8a 导出报错 error while loading shared libraries 等
  • 原文地址:https://blog.csdn.net/hys__handsome/article/details/126462800