6060
6161### 方法一:DFS
6262
63- 相似题目:
63+ 我们设计一个函数 $\textit{dfs}(root)$,表示以 $\textit{root}$ 节点作为路径的其中一个端点,向下延伸的最长同值路径长度。
6464
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$ 为二叉树的节点个数。
6676
6777<!-- tabs:start -->
6878
@@ -76,16 +86,16 @@ tags:
7686# self.left = left
7787# self.right = right
7888class 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 :
8191 if root is None :
8292 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
8696 nonlocal ans
87- ans = max (ans, left + right )
88- return max (left, right )
97+ ans = max (ans, l + r )
98+ return max (l, r )
8999
90100 ans = 0
91101 dfs(root)
@@ -114,7 +124,6 @@ class Solution {
114124 private int ans;
115125
116126 public int longestUnivaluePath (TreeNode root ) {
117- ans = 0 ;
118127 dfs(root);
119128 return ans;
120129 }
@@ -123,12 +132,12 @@ class Solution {
123132 if (root == null ) {
124133 return 0 ;
125134 }
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 );
132141 }
133142}
134143```
@@ -149,22 +158,22 @@ class Solution {
149158 */
150159class Solution {
151160public:
152- int ans;
153-
154161 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);
157175 return ans;
158176 }
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- }
168177};
169178```
170179
@@ -179,29 +188,28 @@ public:
179188 * Right *TreeNode
180189 * }
181190 */
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
185193 dfs = func(root *TreeNode) int {
186194 if root == nil {
187195 return 0
188196 }
189- left, right := dfs(root.Left), dfs(root.Right)
197+ l, r := dfs(root.Left), dfs(root.Right)
190198 if root.Left != nil && root.Left.Val == root.Val {
191- left ++
199+ l ++
192200 } else {
193- left = 0
201+ l = 0
194202 }
195203 if root.Right != nil && root.Right.Val == root.Val {
196- right ++
204+ r ++
197205 } else {
198- right = 0
206+ r = 0
199207 }
200- ans = max(ans, left+right )
201- return max(left, right )
208+ ans = max(ans, l+r )
209+ return max(l, r )
202210 }
203211 dfs(root)
204- return ans
212+ return
205213}
206214```
207215
@@ -223,28 +231,19 @@ func longestUnivaluePath(root *TreeNode) int {
223231 */
224232
225233function 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 ) {
233237 return 0 ;
234238 }
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 );
245244 };
246- dfs (root , root . val );
247- return res ;
245+ dfs (root );
246+ return ans ;
248247}
249248```
250249
@@ -271,19 +270,23 @@ function longestUnivaluePath(root: TreeNode | null): number {
271270// }
272271use std :: cell :: RefCell ;
273272use std :: rc :: Rc ;
273+
274274impl 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 {
276276 if root . is_none () {
277277 return 0 ;
278278 }
279279
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+
284286 if root . val == target {
285287 return left . max (right ) + 1 ;
286288 }
289+
287290 0
288291 }
289292
@@ -292,13 +295,9 @@ impl Solution {
292295 return 0 ;
293296 }
294297
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
302301 }
303302}
304303```
@@ -320,16 +319,15 @@ impl Solution {
320319 */
321320var longestUnivaluePath = function (root ) {
322321 let ans = 0 ;
323- let dfs = function ( root ) {
322+ const dfs = root => {
324323 if (! root) {
325324 return 0 ;
326325 }
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);
333331 };
334332 dfs (root);
335333 return ans;
@@ -347,29 +345,24 @@ var longestUnivaluePath = function (root) {
347345 * struct TreeNode *right;
348346 * };
349347 */
350-
351348#define max (a, b ) (((a) > (b)) ? (a) : (b))
352349
353- int dfs (struct TreeNode * root , int target , int * res ) {
350+ int dfs (struct TreeNode* root, int* ans ) {
354351 if (!root) {
355352 return 0;
356353 }
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);
364360}
365361
366362int 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;
373366}
374367```
375368
0 commit comments