5858
5959** 方法一:DFS**
6060
61- 将图视为无向图。从编号 0 开始 dfs,如果遇到正向边,则需要累加一次变更。
61+ 题目给定的路线图中有 $n$ 个节点和 $n-1$ 条边,如果我们忽略边的方向,那么这 $n$ 个节点构成了一棵树。而题目需要我们改变某些边的方向,使得每个节点都能到达节点 $0$。
62+
63+ 我们不妨考虑从节点 $0$ 出发,到达其他所有节点。方向与题目描述相反,意味着我们在构建图的时候,对于有向边 $[ a, b] $,我们应该视为有向边 $[ b, a] $。也即是说,如果要从 $a$ 到 $b$,我们需要变更一次方向;如果要从 $b$ 到 $a$,则不需要变更方向。
64+
65+ 接下来,我们只需要从节点 $0$ 出发,搜索其他所有节点,过程中,如果遇到需要变更方向的边,则累加一次变更方向的次数。
66+
67+ 时间复杂度 $O(n)$,空间复杂度 $O(n)$。其中 $n$ 是题目中节点的数量。
6268
6369<!-- tabs:start -->
6470
6975``` python
7076class Solution :
7177 def minReorder (self , n : int , connections : List[List[int ]]) -> int :
72- def dfs (u ):
73- vis[u] = True
74- ans = 0
75- for v in g[u]:
76- if not vis[v]:
77- if (u, v) in s:
78- ans += 1
79- ans += dfs(v)
80- return ans
81-
82- g = defaultdict(list )
83- s = set ()
78+ def dfs (a : int , fa : int ) -> int :
79+ return sum (c + dfs(b, a) for b, c in g[a] if b != fa)
80+
81+ g = [[] for _ in range (n)]
8482 for a, b in connections:
85- g[a].append(b)
86- g[b].append(a)
87- s.add((a, b))
88- vis = [False ] * n
89- return dfs(0 )
83+ g[a].append((b, 1 ))
84+ g[b].append((a, 0 ))
85+ return dfs(0 , - 1 )
9086```
9187
9288### ** Java**
@@ -95,28 +91,25 @@ class Solution:
9591
9692``` java
9793class Solution {
94+ private List<int[]> [] g;
95+
9896 public int minReorder (int n , int [][] connections ) {
99- Map<Integer , List<Pair<Integer , Boolean > > > g = new HashMap<> ();
100- for (int [] e : connections) {
101- int u = e[0 ], v = e[1 ];
102- g. computeIfAbsent(u, k - > new ArrayList<> ()). add(new Pair<> (v, true ));
103- g. computeIfAbsent(v, k - > new ArrayList<> ()). add(new Pair<> (u, false ));
97+ g = new List [n];
98+ Arrays . setAll(g, k - > new ArrayList<> ());
99+ for (var e : connections) {
100+ int a = e[0 ], b = e[1 ];
101+ g[a]. add(new int [] {b, 1 });
102+ g[b]. add(new int [] {a, 0 });
104103 }
105- boolean [] vis = new boolean [n];
106- return dfs(0 , g, vis);
104+ return dfs(0 , - 1 );
107105 }
108106
109- private int dfs (int u , Map<Integer , List<Pair<Integer , Boolean > > > g , boolean [] vis ) {
110- vis[u] = true ;
107+ private int dfs (int a , int fa ) {
111108 int ans = 0 ;
112- for (Pair<Integer , Boolean > e : g. getOrDefault(u, Collections . emptyList())) {
113- int v = e. getKey();
114- boolean exist = e. getValue();
115- if (! vis[v]) {
116- if (exist) {
117- ++ ans;
118- }
119- ans += dfs(v, g, vis);
109+ for (var e : g[a]) {
110+ int b = e[0 ], c = e[1 ];
111+ if (b != fa) {
112+ ans += c + dfs(b, a);
120113 }
121114 }
122115 return ans;
@@ -130,28 +123,22 @@ class Solution {
130123class Solution {
131124public:
132125 int minReorder(int n, vector<vector<int >>& connections) {
133- unordered_map<int, vector<pair<int, bool>>> g ;
126+ vector<pair<int, int>> g [ n ] ;
134127 for (auto& e : connections) {
135- int u = e[ 0] , v = e[ 1] ;
136- g[ u ] .push_back({v, true} );
137- g[ v ] .push_back({u, false} );
128+ int a = e[ 0] , b = e[ 1] ;
129+ g[ a ] .emplace_back(b, 1 );
130+ g[ b ] .emplace_back(a, 0 );
138131 }
139- vector<bool > vis(n);
140- return dfs(0, g, vis);
141- }
142-
143- int dfs(int u, unordered_map<int, vector<pair<int, bool>>>& g, vector<bool>& vis) {
144- vis[u] = true;
145- int ans = 0;
146- for (auto& p : g[u]) {
147- int v = p.first;
148- bool exist = p.second;
149- if (!vis[v]) {
150- if (exist) ++ans;
151- ans += dfs(v, g, vis);
132+ function<int(int, int)> dfs = [ &] (int a, int fa) {
133+ int ans = 0;
134+ for (auto& [ b, c] : g[ a] ) {
135+ if (b != fa) {
136+ ans += c + dfs(b, a);
137+ }
152138 }
153- }
154- return ans;
139+ return ans;
140+ };
141+ return dfs(0, -1);
155142 }
156143};
157144```
@@ -160,33 +147,70 @@ public:
160147
161148```go
162149func minReorder(n int, connections [][]int) int {
163- type pib struct {
164- v int
165- b bool
166- }
167- g := map [int ][]pib{}
150+ g := make([][][2]int, n)
168151 for _, e := range connections {
169- u , v := e[0 ], e[1 ]
170- g[u ] = append (g[u ], pib{v, true })
171- g[v ] = append (g[v ], pib{u, false })
152+ a, b := e[0], e[1]
153+ g[a ] = append(g[a ], [2]int{b, 1 })
154+ g[b ] = append(g[b ], [2]int{a, 0 })
172155 }
173- vis := make ([]bool , n)
174- var dfs func (int ) int
175- dfs = func (u int ) int {
176- ans := 0
177- vis[u] = true
178- for _ , p := range g[u] {
179- v , exist := p.v , p.b
180- if !vis[v] {
181- if exist {
182- ans++
183- }
184- ans += dfs (v)
156+ var dfs func(int, int) int
157+ dfs = func(a, fa int) (ans int) {
158+ for _, e := range g[a] {
159+ if b, c := e[0], e[1]; b != fa {
160+ ans += c + dfs(b, a)
185161 }
186162 }
187- return ans
163+ return
188164 }
189- return dfs (0 )
165+ return dfs(0, -1)
166+ }
167+ ```
168+
169+ ### ** TypeScript**
170+
171+ ``` ts
172+ function minReorder(n : number , connections : number [][]): number {
173+ const g: [number , number ][][] = Array .from ({ length: n }, () => []);
174+ for (const [a, b] of connections ) {
175+ g [a ].push ([b , 1 ]);
176+ g [b ].push ([a , 0 ]);
177+ }
178+ const dfs = (a : number , fa : number ): number => {
179+ let ans = 0 ;
180+ for (const [b, c] of g [a ]) {
181+ if (b !== fa ) {
182+ ans += c + dfs (b , a );
183+ }
184+ }
185+ return ans ;
186+ };
187+ return dfs (0 , - 1 );
188+ }
189+ ```
190+
191+ ### ** Rust**
192+
193+ ``` rust
194+ impl Solution {
195+ pub fn min_reorder (n : i32 , connections : Vec <Vec <i32 >>) -> i32 {
196+ let mut g : Vec <Vec <(i32 , i32 )>> = vec! [vec! []; n as usize ];
197+ for e in connections . iter () {
198+ let a = e [0 ] as usize ;
199+ let b = e [1 ] as usize ;
200+ g [a ]. push ((b as i32 , 1 ));
201+ g [b ]. push ((a as i32 , 0 ));
202+ }
203+ fn dfs (a : usize , fa : i32 , g : & Vec <Vec <(i32 , i32 )>>) -> i32 {
204+ let mut ans = 0 ;
205+ for & (b , c ) in g [a ]. iter () {
206+ if b != fa {
207+ ans += c + dfs (b as usize , a as i32 , g );
208+ }
209+ }
210+ ans
211+ }
212+ dfs (0 , - 1 , & g )
213+ }
190214}
191215```
192216
0 commit comments