Leet Code Daily 2024-04-28 - Sum of Distances in Tree
Solution
Let's take node 0 as the root and form the graph as a tree.
By DFS, we can get:
If we define:
Obviously,
And for , considering both parent node and sibling nodes, we can find:
Also we know:
Thus:
And the answer of node i would be .
Code
constexpr int kNotComputed = -1;
constexpr int kRoot = 0;
class Solution {
public:
vector<int> sumOfDistancesInTree(int n, vector<vector<int>>& edges) {
// Build adjacency.
vector<vector<int>> adjacency(n);
for (const auto edge : edges) {
adjacency[edge[0]].push_back(edge[1]);
adjacency[edge[1]].push_back(edge[0]);
}
// DFS to compute P(i) & C(i).
vector<int> P(n, kNotComputed);
vector<vector<int>> C(n);
function<void(int)> dfs;
dfs = [&](int i) {
for (const auto j : adjacency[i]) {
if (P[j] == kNotComputed && j != kRoot) {
P[j] = i;
C[i].push_back(j);
dfs(j);
}
}
};
dfs(kRoot);
// Compute F(i), G(i) & H(i).
vector<int> F(n, kNotComputed), G(n, kNotComputed), H(n, kNotComputed);
function<int(int)> getF, getG, getH;
getF = [&](int i) -> int {
if (F[i] == kNotComputed) {
F[i] = 1;
for (const auto c : C[i]) {
F[i] += getF(c);
}
}
return F[i];
};
getG = [&](int i) -> int {
if (G[i] == kNotComputed) {
G[i] = 0;
for (const auto c : C[i]) {
G[i] += getF(c) + getG(c);
}
}
return G[i];
};
getH = [&](int i) -> int {
if (H[i] == kNotComputed) {
H[i] = (i == kRoot) ? 0
: (H[i] = getH(P[i]) + n + getG(P[i]) -
getG(i) - 2 * getF(i));
}
return H[i];
};
// Build answer.
vector<int> answer;
for (int i = 0; i < n; i++) {
answer.push_back(getG(i) + getH(i));
}
return answer;
}
};