
題目解析: 給定一組變數相除的方程式與結果,求出新查詢的相除結果,若無法計算則回傳 -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;
}
};

題目解析: 城市間有單向道路,求最少需要翻轉幾條道路的方向,才能讓所有城市都能走到城市 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;
}
};

哈哈,終於結束啦!