Skip to content

feat: add solutions to lc problem: No.1466 #2063

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Dec 4, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,13 @@

**方法一:DFS**

将图视为无向图。从编号 0 开始 dfs,如果遇到正向边,则需要累加一次变更。
题目给定的路线图中有 $n$ 个节点和 $n-1$ 条边,如果我们忽略边的方向,那么这 $n$ 个节点构成了一棵树。而题目需要我们改变某些边的方向,使得每个节点都能到达节点 $0$。

我们不妨考虑从节点 $0$ 出发,到达其他所有节点。方向与题目描述相反,意味着我们在构建图的时候,对于有向边 $[a, b]$,我们应该视为有向边 $[b, a]$。也即是说,如果要从 $a$ 到 $b$,我们需要变更一次方向;如果要从 $b$ 到 $a$,则不需要变更方向。

接下来,我们只需要从节点 $0$ 出发,搜索其他所有节点,过程中,如果遇到需要变更方向的边,则累加一次变更方向的次数。

时间复杂度 $O(n)$,空间复杂度 $O(n)$。其中 $n$ 是题目中节点的数量。

<!-- tabs:start -->

Expand All @@ -69,24 +75,14 @@
```python
class Solution:
def minReorder(self, n: int, connections: List[List[int]]) -> int:
def dfs(u):
vis[u] = True
ans = 0
for v in g[u]:
if not vis[v]:
if (u, v) in s:
ans += 1
ans += dfs(v)
return ans

g = defaultdict(list)
s = set()
def dfs(a: int, fa: int) -> int:
return sum(c + dfs(b, a) for b, c in g[a] if b != fa)

g = [[] for _ in range(n)]
for a, b in connections:
g[a].append(b)
g[b].append(a)
s.add((a, b))
vis = [False] * n
return dfs(0)
g[a].append((b, 1))
g[b].append((a, 0))
return dfs(0, -1)
```

### **Java**
Expand All @@ -95,28 +91,25 @@ class Solution:

```java
class Solution {
private List<int[]>[] g;

public int minReorder(int n, int[][] connections) {
Map<Integer, List<Pair<Integer, Boolean>>> g = new HashMap<>();
for (int[] e : connections) {
int u = e[0], v = e[1];
g.computeIfAbsent(u, k -> new ArrayList<>()).add(new Pair<>(v, true));
g.computeIfAbsent(v, k -> new ArrayList<>()).add(new Pair<>(u, false));
g = new List[n];
Arrays.setAll(g, k -> new ArrayList<>());
for (var e : connections) {
int a = e[0], b = e[1];
g[a].add(new int[] {b, 1});
g[b].add(new int[] {a, 0});
}
boolean[] vis = new boolean[n];
return dfs(0, g, vis);
return dfs(0, -1);
}

private int dfs(int u, Map<Integer, List<Pair<Integer, Boolean>>> g, boolean[] vis) {
vis[u] = true;
private int dfs(int a, int fa) {
int ans = 0;
for (Pair<Integer, Boolean> e : g.getOrDefault(u, Collections.emptyList())) {
int v = e.getKey();
boolean exist = e.getValue();
if (!vis[v]) {
if (exist) {
++ans;
}
ans += dfs(v, g, vis);
for (var e : g[a]) {
int b = e[0], c = e[1];
if (b != fa) {
ans += c + dfs(b, a);
}
}
return ans;
Expand All @@ -130,28 +123,22 @@ class Solution {
class Solution {
public:
int minReorder(int n, vector<vector<int>>& connections) {
unordered_map<int, vector<pair<int, bool>>> g;
vector<pair<int, int>> g[n];
for (auto& e : connections) {
int u = e[0], v = e[1];
g[u].push_back({v, true});
g[v].push_back({u, false});
int a = e[0], b = e[1];
g[a].emplace_back(b, 1);
g[b].emplace_back(a, 0);
}
vector<bool> vis(n);
return dfs(0, g, vis);
}

int dfs(int u, unordered_map<int, vector<pair<int, bool>>>& g, vector<bool>& vis) {
vis[u] = true;
int ans = 0;
for (auto& p : g[u]) {
int v = p.first;
bool exist = p.second;
if (!vis[v]) {
if (exist) ++ans;
ans += dfs(v, g, vis);
function<int(int, int)> dfs = [&](int a, int fa) {
int ans = 0;
for (auto& [b, c] : g[a]) {
if (b != fa) {
ans += c + dfs(b, a);
}
}
}
return ans;
return ans;
};
return dfs(0, -1);
}
};
```
Expand All @@ -160,33 +147,70 @@ public:

```go
func minReorder(n int, connections [][]int) int {
type pib struct {
v int
b bool
}
g := map[int][]pib{}
g := make([][][2]int, n)
for _, e := range connections {
u, v := e[0], e[1]
g[u] = append(g[u], pib{v, true})
g[v] = append(g[v], pib{u, false})
a, b := e[0], e[1]
g[a] = append(g[a], [2]int{b, 1})
g[b] = append(g[b], [2]int{a, 0})
}
vis := make([]bool, n)
var dfs func(int) int
dfs = func(u int) int {
ans := 0
vis[u] = true
for _, p := range g[u] {
v, exist := p.v, p.b
if !vis[v] {
if exist {
ans++
}
ans += dfs(v)
var dfs func(int, int) int
dfs = func(a, fa int) (ans int) {
for _, e := range g[a] {
if b, c := e[0], e[1]; b != fa {
ans += c + dfs(b, a)
}
}
return ans
return
}
return dfs(0)
return dfs(0, -1)
}
```

### **TypeScript**

```ts
function minReorder(n: number, connections: number[][]): number {
const g: [number, number][][] = Array.from({ length: n }, () => []);
for (const [a, b] of connections) {
g[a].push([b, 1]);
g[b].push([a, 0]);
}
const dfs = (a: number, fa: number): number => {
let ans = 0;
for (const [b, c] of g[a]) {
if (b !== fa) {
ans += c + dfs(b, a);
}
}
return ans;
};
return dfs(0, -1);
}
```

### **Rust**

```rust
impl Solution {
pub fn min_reorder(n: i32, connections: Vec<Vec<i32>>) -> i32 {
let mut g: Vec<Vec<(i32, i32)>> = vec![vec![]; n as usize];
for e in connections.iter() {
let a = e[0] as usize;
let b = e[1] as usize;
g[a].push((b as i32, 1));
g[b].push((a as i32, 0));
}
fn dfs(a: usize, fa: i32, g: &Vec<Vec<(i32, i32)>>) -> i32 {
let mut ans = 0;
for &(b, c) in g[a].iter() {
if b != fa {
ans += c + dfs(b as usize, a as i32, g);
}
}
ans
}
dfs(0, -1, &g)
}
}
```

Expand Down
Loading