60
60
61
61
### 方法一:DFS
62
62
63
- 相似题目:
63
+ 我们设计一个函数 $\textit{dfs}(root)$,表示以 $\textit{root}$ 节点作为路径的其中一个端点,向下延伸的最长同值路径长度。
64
64
65
- - [ 543. 二叉树的直径] ( https://github.com/doocs/leetcode/blob/main/solution/0500-0599/0543.Diameter%20of%20Binary%20Tree/README.md )
65
+ 在 $\textit{dfs}(root)$ 中,我们首先递归调用 $\textit{dfs}(root.\textit{left})$ 和 $\textit{dfs}(root.\textit{right})$,得到两个返回值 $\textit{l}$ 和 $\textit{r}$。这两个返回值分别代表了以 $\textit{root}$ 节点的左孩子和右孩子为路径的其中一个端点,向下延伸的最长同值路径长度。
66
+
67
+ 如果 $\textit{root}$ 存在左孩子且 $\textit{root}.\textit{val} = \textit{root}.\textit{left}.\textit{val}$,那么在 $\textit{root}$ 的左孩子为路径的其中一个端点,向下延伸的最长同值路径长度应为 $\textit{l} + 1$;否则,这个长度为 $0$。如果 $\textit{root}$ 存在右孩子且 $\textit{root}.\textit{val} = \textit{root}.\textit{right}.\textit{val}$,那么在 $\textit{root}$ 的右孩子为路径的其中一个端点,向下延伸的最长同值路径长度应为 $\textit{r} + 1$;否则,这个长度为 $0$。
68
+
69
+ 在递归调用完左右孩子之后,我们更新答案为 $\max(\textit{ans}, \textit{l} + \textit{r})$,即以 $\textit{root}$ 为端点的路径经过 $\textit{root}$ 的最长同值路径长度。
70
+
71
+ 最后,$\textit{dfs}(root)$ 函数返回以 $\textit{root}$ 为端点的向下延伸的最长同值路径长度,即 $\max(\textit{l}, \textit{r})$。
72
+
73
+ 在主函数中,我们调用 $\textit{dfs}(root)$,即可得到答案。
74
+
75
+ 时间复杂度 $O(n)$,空间复杂度 $O(n)$。其中 $n$ 为二叉树的节点个数。
66
76
67
77
<!-- tabs:start -->
68
78
@@ -76,16 +86,16 @@ tags:
76
86
# self.left = left
77
87
# self.right = right
78
88
class Solution :
79
- def longestUnivaluePath (self , root : TreeNode) -> int :
80
- def dfs (root ) :
89
+ def longestUnivaluePath (self , root : Optional[ TreeNode] ) -> int :
90
+ def dfs (root : Optional[TreeNode]) -> int :
81
91
if root is None :
82
92
return 0
83
- left, right = dfs(root.left), dfs(root.right)
84
- left = left + 1 if root.left and root.left.val == root.val else 0
85
- right = right + 1 if root.right and root.right.val == root.val else 0
93
+ l, r = dfs(root.left), dfs(root.right)
94
+ l = l + 1 if root.left and root.left.val == root.val else 0
95
+ r = r + 1 if root.right and root.right.val == root.val else 0
86
96
nonlocal ans
87
- ans = max (ans, left + right )
88
- return max (left, right )
97
+ ans = max (ans, l + r )
98
+ return max (l, r )
89
99
90
100
ans = 0
91
101
dfs(root)
@@ -114,7 +124,6 @@ class Solution {
114
124
private int ans;
115
125
116
126
public int longestUnivaluePath (TreeNode root ) {
117
- ans = 0 ;
118
127
dfs(root);
119
128
return ans;
120
129
}
@@ -123,12 +132,12 @@ class Solution {
123
132
if (root == null ) {
124
133
return 0 ;
125
134
}
126
- int left = dfs(root. left);
127
- int right = dfs(root. right);
128
- left = root. left != null && root. left. val == root. val ? left + 1 : 0 ;
129
- right = root. right != null && root. right. val == root. val ? right + 1 : 0 ;
130
- ans = Math . max(ans, left + right );
131
- return Math . max(left, right );
135
+ int l = dfs(root. left);
136
+ int r = dfs(root. right);
137
+ l = root. left != null && root. left. val == root. val ? l + 1 : 0 ;
138
+ r = root. right != null && root. right. val == root. val ? r + 1 : 0 ;
139
+ ans = Math . max(ans, l + r );
140
+ return Math . max(l, r );
132
141
}
133
142
}
134
143
```
@@ -149,22 +158,22 @@ class Solution {
149
158
*/
150
159
class Solution {
151
160
public:
152
- int ans;
153
-
154
161
int longestUnivaluePath(TreeNode* root) {
155
- ans = 0;
156
- dfs(root);
162
+ int ans = 0;
163
+ auto dfs = [ &] (auto&& dfs, TreeNode* root) -> int {
164
+ if (!root) {
165
+ return 0;
166
+ }
167
+ int l = dfs(dfs, root->left);
168
+ int r = dfs(dfs, root->right);
169
+ l = root->left && root->left->val == root->val ? l + 1 : 0;
170
+ r = root->right && root->right->val == root->val ? r + 1 : 0;
171
+ ans = max(ans, l + r);
172
+ return max(l, r);
173
+ };
174
+ dfs(dfs, root);
157
175
return ans;
158
176
}
159
-
160
- int dfs (TreeNode* root) {
161
- if (!root) return 0;
162
- int left = dfs(root->left), right = dfs(root->right);
163
- left = root->left && root->left->val == root->val ? left + 1 : 0;
164
- right = root->right && root->right->val == root->val ? right + 1 : 0;
165
- ans = max(ans, left + right);
166
- return max(left, right);
167
- }
168
177
};
169
178
```
170
179
@@ -179,29 +188,28 @@ public:
179
188
* Right *TreeNode
180
189
* }
181
190
*/
182
- func longestUnivaluePath(root *TreeNode) int {
183
- ans := 0
184
- var dfs func(root *TreeNode) int
191
+ func longestUnivaluePath(root *TreeNode) (ans int) {
192
+ var dfs func(*TreeNode) int
185
193
dfs = func(root *TreeNode) int {
186
194
if root == nil {
187
195
return 0
188
196
}
189
- left, right := dfs(root.Left), dfs(root.Right)
197
+ l, r := dfs(root.Left), dfs(root.Right)
190
198
if root.Left != nil && root.Left.Val == root.Val {
191
- left ++
199
+ l ++
192
200
} else {
193
- left = 0
201
+ l = 0
194
202
}
195
203
if root.Right != nil && root.Right.Val == root.Val {
196
- right ++
204
+ r ++
197
205
} else {
198
- right = 0
206
+ r = 0
199
207
}
200
- ans = max(ans, left+right )
201
- return max(left, right )
208
+ ans = max(ans, l+r )
209
+ return max(l, r )
202
210
}
203
211
dfs(root)
204
- return ans
212
+ return
205
213
}
206
214
```
207
215
@@ -223,28 +231,19 @@ func longestUnivaluePath(root *TreeNode) int {
223
231
*/
224
232
225
233
function longestUnivaluePath(root : TreeNode | null ): number {
226
- if (root == null ) {
227
- return 0 ;
228
- }
229
-
230
- let res = 0 ;
231
- const dfs = (root : TreeNode | null , target : number ) => {
232
- if (root == null ) {
234
+ let ans: number = 0 ;
235
+ const dfs = (root : TreeNode | null ): number => {
236
+ if (! root ) {
233
237
return 0 ;
234
238
}
235
-
236
- const { val, left, right } = root ;
237
-
238
- let l = dfs (left , val );
239
- let r = dfs (right , val );
240
- res = Math .max (res , l + r );
241
- if (val === target ) {
242
- return Math .max (l , r ) + 1 ;
243
- }
244
- return 0 ;
239
+ let [l, r] = [dfs (root .left ), dfs (root .right )];
240
+ l = root .left && root .left .val === root .val ? l + 1 : 0 ;
241
+ r = root .right && root .right .val === root .val ? r + 1 : 0 ;
242
+ ans = Math .max (ans , l + r );
243
+ return Math .max (l , r );
245
244
};
246
- dfs (root , root . val );
247
- return res ;
245
+ dfs (root );
246
+ return ans ;
248
247
}
249
248
```
250
249
@@ -271,19 +270,23 @@ function longestUnivaluePath(root: TreeNode | null): number {
271
270
// }
272
271
use std :: cell :: RefCell ;
273
272
use std :: rc :: Rc ;
273
+
274
274
impl Solution {
275
- fn dfs (root : & Option <Rc <RefCell <TreeNode >>>, target : i32 , res : & mut i32 ) -> i32 {
275
+ fn dfs (root : & Option <Rc <RefCell <TreeNode >>>, target : i32 , ans : & mut i32 ) -> i32 {
276
276
if root . is_none () {
277
277
return 0 ;
278
278
}
279
279
280
- let root = root . as_ref (). unwrap (). as_ref (). borrow ();
281
- let left = Self :: dfs (& root . left, root . val, res );
282
- let right = Self :: dfs (& root . right, root . val, res );
283
- * res = (* res ). max (left + right );
280
+ let root = root . as_ref (). unwrap (). borrow ();
281
+ let left = Self :: dfs (& root . left, root . val, ans );
282
+ let right = Self :: dfs (& root . right, root . val, ans );
283
+
284
+ * ans = (* ans ). max (left + right );
285
+
284
286
if root . val == target {
285
287
return left . max (right ) + 1 ;
286
288
}
289
+
287
290
0
288
291
}
289
292
@@ -292,13 +295,9 @@ impl Solution {
292
295
return 0 ;
293
296
}
294
297
295
- let mut res = 0 ;
296
- Self :: dfs (
297
- & root ,
298
- root . as_ref (). unwrap (). as_ref (). borrow (). val,
299
- & mut res ,
300
- );
301
- res
298
+ let mut ans = 0 ;
299
+ Self :: dfs (& root , root . as_ref (). unwrap (). borrow (). val, & mut ans );
300
+ ans
302
301
}
303
302
}
304
303
```
@@ -320,16 +319,15 @@ impl Solution {
320
319
*/
321
320
var longestUnivaluePath = function (root ) {
322
321
let ans = 0 ;
323
- let dfs = function ( root ) {
322
+ const dfs = root => {
324
323
if (! root) {
325
324
return 0 ;
326
325
}
327
- let left = dfs (root .left ),
328
- right = dfs (root .right );
329
- left = root .left ? .val == root .val ? left + 1 : 0 ;
330
- right = root .right ? .val == root .val ? right + 1 : 0 ;
331
- ans = Math .max (ans, left + right);
332
- return Math .max (left, right);
326
+ let [l, r] = [dfs (root .left ), dfs (root .right )];
327
+ l = root .left && root .left .val === root .val ? l + 1 : 0 ;
328
+ r = root .right && root .right .val === root .val ? r + 1 : 0 ;
329
+ ans = Math .max (ans, l + r);
330
+ return Math .max (l, r);
333
331
};
334
332
dfs (root);
335
333
return ans;
@@ -347,29 +345,24 @@ var longestUnivaluePath = function (root) {
347
345
* struct TreeNode *right;
348
346
* };
349
347
*/
350
-
351
348
#define max (a, b ) (((a) > (b)) ? (a) : (b))
352
349
353
- int dfs (struct TreeNode * root , int target , int * res ) {
350
+ int dfs (struct TreeNode* root, int* ans ) {
354
351
if (!root) {
355
352
return 0;
356
353
}
357
- int left = dfs (root- > left, root- > val, res);
358
- int right = dfs (root- > right, root- > val, res);
359
- * res = max (* res, left + right);
360
- if (root- > val == target) {
361
- return max (left, right) + 1 ;
362
- }
363
- return 0 ;
354
+ int l = dfs(root->left, ans);
355
+ int r = dfs(root->right, ans);
356
+ l = root->left && root->left->val == root->val ? l + 1 : 0;
357
+ r = root->right && root->right->val == root->val ? r + 1 : 0;
358
+ * ans = max(* ans, l + r);
359
+ return max(l, r);
364
360
}
365
361
366
362
int longestUnivaluePath(struct TreeNode* root) {
367
- if (! root) {
368
- return 0 ;
369
- }
370
- int res = 0 ;
371
- dfs (root, root- > val, & res);
372
- return res;
363
+ int ans = 0;
364
+ dfs(root, &ans);
365
+ return ans;
373
366
}
374
367
```
375
368
0 commit comments