Skip to content

Commit b36a630

Browse files
authored
feat: update solutions to lc problem: No.0687 (doocs#3682)
No.0687.Longest Univalue Path
1 parent e307732 commit b36a630

File tree

10 files changed

+253
-280
lines changed

10 files changed

+253
-280
lines changed

solution/0600-0699/0687.Longest Univalue Path/README.md

Lines changed: 86 additions & 93 deletions
Original file line numberDiff line numberDiff line change
@@ -60,9 +60,19 @@ tags:
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
7888
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:
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
*/
150159
class Solution {
151160
public:
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

225233
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) {
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
// }
272271
use std::cell::RefCell;
273272
use std::rc::Rc;
273+
274274
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 {
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
*/
321320
var 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

366362
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;
373366
}
374367
```
375368

0 commit comments

Comments
 (0)