iT邦幫忙

2026 iThome 鐵人賽

DAY 30
0
Software Development

30天刷完leetcoode75系列 第 30 篇

C++ 演算法練習 Day6|399, 1466 題解與思路分享

  • 分享至 

  • xImage
  •  

https://ithelp.ithome.com.tw/upload/images/20261014/20184265cpBwq4VsqR.png

題目解析: 給定一組變數相除的方程式與結果,求出新查詢的相除結果,若無法計算則回傳 -1.0。
解題思路: 把方程式轉換成有向圖,變數當作節點,相除的值當作邊的權重(反向邊的權重就是倒數)。設雜湊表 v 建圖,陣列 ans 裝答案。對每個查詢,若變數不存在圖中直接給 -1.0;否則利用 DFS 遞迴走訪,把路徑上的權重相乘,找到目標節點就回傳結果。

class Solution {
public:
    unordered_map<string, vector<pair<string, double>>> v;
    vector<double> ans;

    void solve(string now, string target, double cur, unordered_set<string>& vis, double& res) {
        if (now == target) {
            res = cur;
            return;
        }
        vis.insert(now);
        for (auto& it : v[now]) {
            if (!vis.count(it.first)) {
                solve(it.first, target, cur * it.second, vis, res);
            }
        }
    }

    vector<double> calcEquation(vector<vector<string>>& equations, vector<double>& values, vector<vector<string>>& queries) {
        for (int i = 0; i < equations.size(); i++) {
            v[equations[i][0]].push_back({equations[i][1], values[i]});
            v[equations[i][1]].push_back({equations[i][0], 1.0 / values[i]});
        }
        for (auto& q : queries) {
            if (!v.count(q[0]) || !v.count(q[1])) {
                ans.push_back(-1.0);
            } else {
                double res = -1.0;
                unordered_set<string> vis;
                solve(q[0], q[1], 1.0, vis, res);
                ans.push_back(res);
            }
        }
        return ans;
    }
};

https://ithelp.ithome.com.tw/upload/images/20261014/20184265tZsesBD9ja.png

題目解析: 城市間有單向道路,求最少需要翻轉幾條道路的方向,才能讓所有城市都能走到城市 0。
解題思路: 逆向思考,把城市 0 當作起點向外走訪。設陣列 v 建立無向圖,並在儲存相鄰節點時,用 1 和 0 標記邊是否為「原本遠離 0 的方向」。寫一個 DFS 遞迴從 0 開始遍歷,只要走到標記為 1 的邊,代表該方向會讓車子開走,必須翻轉,就把 ans 加 1。走訪完所有城市即可得解。

class Solution {
public:
    int ans = 0;
    vector<vector<pair<int, int>>> v;

    void solve(int now, int parent) {
        for (auto& it : v[now]) {
            if (it.first != parent) {
                ans += it.second;
                solve(it.first, now);
            }
        }
    }

    int minReorder(int n, vector<vector<int>>& connections) {
        v.resize(n);
        for (auto& c : connections) {
            v[c[0]].push_back({c[1], 1});
            v[c[1]].push_back({c[0], 0});
        }
        solve(0, -1);
        return ans;
    }
};

https://ithelp.ithome.com.tw/upload/images/20261014/2018426582YsHDLG1w.png
哈哈,終於結束啦!


上一篇
C++ 演算法練習 Day29|450, 1493 題解與思路分享
系列文
30天刷完leetcoode75 共 30 篇
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言