Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit de485bc

Browse files
committed
Update 0543. 二叉树的直径.md
1 parent 6819829 commit de485bc

File tree

1 file changed

+42
-19
lines changed

1 file changed

+42
-19
lines changed

‎Solutions/0543. 二叉树的直径.md‎

Lines changed: 42 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,15 @@
55

66
## 题目大意
77

8-
**描述**:给一个二叉树的根节点 `root`
8+
**描述**:给一个二叉树的根节点 $root$
99

1010
**要求**:计算该二叉树的直径长度。
1111

1212
**说明**:
1313

1414
- **二叉树的直径长度**:二叉树中任意两个节点路径长度中的最大值。
1515
- 两节点之间的路径长度是以它们之间边的数目表示。
16+
- 这条路径可能穿过也可能不穿过根节点。
1617

1718
**示例**:
1819

@@ -31,36 +32,58 @@
3132

3233
## 解题思路
3334

34-
### 思路 1:深度优先搜索
35+
### 思路 1:树形 DP + 深度优先搜索
3536

36-
这道题的重点是理解直径长度的定义。这里的直径并不是简单的「左子树高度」+「右子树高度」
37+
这道题重点是理解直径长度的定义。「二叉树的直径长度」的定义为:二叉树中任意两个节点路径长度中的最大值。并且这条路径可能穿过也可能不穿过根节点
3738

38-
而是 `当前节点的直径 = max{左子树高度+右子树高度,所有子树中最大直径}`
39+
对于根为 $root$ 的二叉树来说,其直径长度并不简单等于「左子树高度」加上「右子树高度
3940

40-
也就是说当前节点的直径可能来自于 「左子树高度」+「右子树高度」,也可能来自于「子树中的最大直径」。
41+
根据路径是否穿过根节点,我们可以将二叉树分为两种:
4142

42-
这就需要在递归求解子树高度的时候维护一个 `maxDiameter` 变量。每次递归都要去判断 当前「左子树高度」+「右子树的高度」是否大于 `self.maxDiameter`,如果大于,则更新最大值。
43+
1. 直径长度所对应的路径穿过根节点。
44+
2. 直径长度所对应的路径不穿过根节点。
45+
46+
我们来看下图中的两个例子。
47+
48+
![](https://qcdn.itcharge.cn/images/20230427111005.png)
49+
50+
如图所示,左侧这棵二叉树就是一棵常见的平衡二叉树,其直径长度所对应的路径是穿过根节点的($D\rightarrow B \rightarrow A \rightarrow C$)。这种情况下:$二叉树的直径 = 左子树高度 + 右子树高度$。
51+
52+
而右侧这棵特殊的二叉树,其直径长度所对应的路径是没有穿过根节点的($F \rightarrow D \rightarrow B \rightarrow E \rightarrow G$)。这种情况下:$二叉树的直径 = 所有子树中最大直径长度$。
53+
54+
也就是说根为 $root$ 的二叉树的直径长度可能来自于 $左子树高度 + 右子树高度,ドル也可能来自于 $子树中的最大直径,ドル即 $二叉树的直径 = max(左子树高度 + 右子树高度, \quad 所有子树中最大直径长度)$。
55+
56+
那么现在问题就变成为如何求「子树的高度」和「子树中的最大直径」。
57+
58+
1. 子树的高度:我们可以利用深度优先搜索方法,递归遍历左右子树,并分别返回左右子树的高度。
59+
2. 子树中的最大直径:我们可以在递归求解子树高度的时候维护一个 $ans$ 变量,用于记录所有 $左子树高度 + 右子树高度$ 中的最大值。
60+
61+
最终 $ans$ 就是我们所求的该二叉树的最大直径,将其返回即可。
4362

4463
### 思路 1:代码
4564

4665
```Python
66+
# Definition for a binary tree node.
67+
# class TreeNode:
68+
# def __init__(self, val=0, left=None, right=None):
69+
# self.val = val
70+
# self.left = left
71+
# self.right = right
4772
class Solution:
4873
def __init__(self):
49-
# 保存当前最大直径
50-
self.maxDiameter = 0
74+
self.ans = 0
5175

52-
def diameterOfBinaryTree(self, root: TreeNode) -> int:
53-
self.height(root)
54-
return self.maxDiameter
55-
56-
def height(self, root):
57-
if root == None:
76+
def dfs(self, node):
77+
if not node:
5878
return 0
59-
leftHeight = self.height(root.left)
60-
rightHeight = self.height(root.right)
61-
self.maxDiameter = max(self.maxDiameter, leftHeight + rightHeight)
62-
63-
return max(leftHeight, rightHeight) + 1
79+
left_height = self.dfs(node.left) # 左子树高度
80+
right_height = self.dfs(node.right) # 右子树高度
81+
self.ans = max(self.ans, left_height + right_height) # 维护所有路径中的最大直径
82+
return max(left_height, right_height) + 1 # 返回该节点的高度 = 左右子树最大高度 + 1
83+
84+
def diameterOfBinaryTree(self, root: Optional[TreeNode]) -> int:
85+
self.dfs(root)
86+
return self.ans
6487
```
6588

6689
### 思路 1:复杂度分析

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /