Skip to content

Commit 0fbdfd7

Browse files
committed
feat: add solutions to lc problem: No.1373
No.1373.Maximum Sum BST in Binary Tree
1 parent ff28e79 commit 0fbdfd7

File tree

7 files changed

+567
-1
lines changed

7 files changed

+567
-1
lines changed

solution/1300-1399/1373.Maximum Sum BST in Binary Tree/README.md

Lines changed: 214 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,22 +73,235 @@
7373

7474
<!-- 这里可写通用的实现逻辑 -->
7575

76+
**方法一:DFS**
77+
78+
判断一棵树是否是二叉搜索树,需要满足以下四个条件:
79+
80+
- 左子树是二叉搜索树;
81+
- 右子树是二叉搜索树;
82+
- 左子树的最大值小于根节点的值;
83+
- 右子树的最小值大于根节点的值。
84+
85+
因此,我们设计一个函数 $dfs(root)$,函数的返回值是一个四元组 $(bst, mi, mx, s)$,其中:
86+
87+
- 数字 $bst$ 表示以 $root$ 为根的树是否是二叉搜索树。如果是二叉搜索树,则 $bst = 1$;否则 $bst = 0$;
88+
- 数字 $mi$ 表示以 $root$ 为根的树的最小值;
89+
- 数字 $mx$ 表示以 $root$ 为根的树的最大值;
90+
- 数字 $s$ 表示以 $root$ 为根的树的所有节点的和。
91+
92+
函数 $dfs(root)$ 的执行逻辑如下:
93+
94+
如果 $root$ 为空节点,则返回 $(1, +\infty, -\infty, 0)$,表示空树是二叉搜索树,最小值和最大值分别为正无穷和负无穷,节点和为 $0$。
95+
96+
否则,递归计算 $root$ 的左子树和右子树,分别得到 $(lbst, lmi, lmx, ls)$ 和 $(rbst, rmi, rmx, rs)$,然后判断 $root$ 节点是否满足二叉搜索树的条件。
97+
98+
如果满足 $lbst = 1$ 且 $rbst = 1$ 且 $lmx \lt root.val \lt rmi$,则以 $root$ 为根的树是二叉搜索树,节点和 $s= ls + rs + root.val$。我们更新答案 $ans = \max(ans, s)$,并返回 $(1, \min(lmi, root.val), \max(rmx, root.val), s)$。
99+
100+
否则,以 $root$ 为根的树不是二叉搜索树,我们返回 $(0, 0, 0, 0)$。
101+
102+
我们在主函数中调用 $dfs(root)$,执行完毕后,答案即为 $ans$。
103+
104+
时间复杂度 $O(n)$,空间复杂度 $O(n)$。其中 $n$ 是二叉树的节点数。
105+
76106
<!-- tabs:start -->
77107

78108
### **Python3**
79109

80110
<!-- 这里可写当前语言的特殊实现逻辑 -->
81111

82112
```python
83-
113+
# Definition for a binary tree node.
114+
# class TreeNode:
115+
# def __init__(self, val=0, left=None, right=None):
116+
# self.val = val
117+
# self.left = left
118+
# self.right = right
119+
class Solution:
120+
def maxSumBST(self, root: Optional[TreeNode]) -> int:
121+
def dfs(root: Optional[TreeNode]) -> tuple:
122+
if root is None:
123+
return 1, inf, -inf, 0
124+
lbst, lmi, lmx, ls = dfs(root.left)
125+
rbst, rmi, rmx, rs = dfs(root.right)
126+
if lbst and rbst and lmx < root.val < rmi:
127+
nonlocal ans
128+
s = ls + rs + root.val
129+
ans = max(ans, s)
130+
return 1, min(lmi, root.val), max(rmx, root.val), s
131+
return 0, 0, 0, 0
132+
133+
ans = 0
134+
dfs(root)
135+
return ans
84136
```
85137

86138
### **Java**
87139

88140
<!-- 这里可写当前语言的特殊实现逻辑 -->
89141

90142
```java
143+
/**
144+
* Definition for a binary tree node.
145+
* public class TreeNode {
146+
* int val;
147+
* TreeNode left;
148+
* TreeNode right;
149+
* TreeNode() {}
150+
* TreeNode(int val) { this.val = val; }
151+
* TreeNode(int val, TreeNode left, TreeNode right) {
152+
* this.val = val;
153+
* this.left = left;
154+
* this.right = right;
155+
* }
156+
* }
157+
*/
158+
class Solution {
159+
private int ans;
160+
private final int inf = 1 << 30;
161+
162+
public int maxSumBST(TreeNode root) {
163+
dfs(root);
164+
return ans;
165+
}
166+
167+
private int[] dfs(TreeNode root) {
168+
if (root == null) {
169+
return new int[] {1, inf, -inf, 0};
170+
}
171+
var l = dfs(root.left);
172+
var r = dfs(root.right);
173+
int v = root.val;
174+
if (l[0] == 1 && r[0] == 1 && l[2] < v && r[1] > v) {
175+
int s = v + l[3] + r[3];
176+
ans = Math.max(ans, s);
177+
return new int[] {1, Math.min(l[1], v), Math.max(r[2], v), s};
178+
}
179+
return new int[4];
180+
}
181+
}
182+
```
183+
184+
### **C++**
185+
186+
```cpp
187+
/**
188+
* Definition for a binary tree node.
189+
* struct TreeNode {
190+
* int val;
191+
* TreeNode *left;
192+
* TreeNode *right;
193+
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
194+
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
195+
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
196+
* };
197+
*/
198+
class Solution {
199+
public:
200+
int maxSumBST(TreeNode* root) {
201+
int ans = 0;
202+
const int inf = 1 << 30;
203+
204+
function<vector<int>(TreeNode*)> dfs = [&](TreeNode* root) {
205+
if (!root) {
206+
return vector<int>{1, inf, -inf, 0};
207+
}
208+
auto l = dfs(root->left);
209+
auto r = dfs(root->right);
210+
int v = root->val;
211+
if (l[0] && r[0] && l[2] < v && v < r[1]) {
212+
int s = l[3] + r[3] + v;
213+
ans = max(ans, s);
214+
return vector<int>{1, min(l[1], v), max(r[2], v), s};
215+
}
216+
return vector<int>(4);
217+
};
218+
dfs(root);
219+
return ans;
220+
}
221+
};
222+
```
223+
224+
### **Go**
225+
226+
```go
227+
/**
228+
* Definition for a binary tree node.
229+
* type TreeNode struct {
230+
* Val int
231+
* Left *TreeNode
232+
* Right *TreeNode
233+
* }
234+
*/
235+
func maxSumBST(root *TreeNode) (ans int) {
236+
const inf = 1 << 30
237+
var dfs func(root *TreeNode) [4]int
238+
dfs = func(root *TreeNode) [4]int {
239+
if root == nil {
240+
return [4]int{1, inf, -inf, 0}
241+
}
242+
l, r := dfs(root.Left), dfs(root.Right)
243+
if l[0] == 1 && r[0] == 1 && l[2] < root.Val && root.Val < r[1] {
244+
s := l[3] + r[3] + root.Val
245+
ans = max(ans, s)
246+
return [4]int{1, min(l[1], root.Val), max(r[2], root.Val), s}
247+
}
248+
return [4]int{}
249+
}
250+
dfs(root)
251+
return
252+
}
253+
254+
func max(a, b int) int {
255+
if a > b {
256+
return a
257+
}
258+
return b
259+
}
260+
261+
func min(a, b int) int {
262+
if a < b {
263+
return a
264+
}
265+
return b
266+
}
267+
```
91268

269+
### **TypeScript**
270+
271+
```ts
272+
/**
273+
* Definition for a binary tree node.
274+
* class TreeNode {
275+
* val: number
276+
* left: TreeNode | null
277+
* right: TreeNode | null
278+
* constructor(val?: number, left?: TreeNode | null, right?: TreeNode | null) {
279+
* this.val = (val===undefined ? 0 : val)
280+
* this.left = (left===undefined ? null : left)
281+
* this.right = (right===undefined ? null : right)
282+
* }
283+
* }
284+
*/
285+
286+
function maxSumBST(root: TreeNode | null): number {
287+
const inf = 1 << 30;
288+
let ans = 0;
289+
const dfs = (root: TreeNode | null): [boolean, number, number, number] => {
290+
if (!root) {
291+
return [true, inf, -inf, 0];
292+
}
293+
const [lbst, lmi, lmx, ls] = dfs(root.left);
294+
const [rbst, rmi, rmx, rs] = dfs(root.right);
295+
if (lbst && rbst && lmx < root.val && root.val < rmi) {
296+
const s = ls + rs + root.val;
297+
ans = Math.max(ans, s);
298+
return [true, Math.min(lmi, root.val), Math.max(rmx, root.val), s];
299+
}
300+
return [false, 0, 0, 0];
301+
};
302+
dfs(root);
303+
return ans;
304+
}
92305
```
93306

94307
### **...**

0 commit comments

Comments
 (0)