Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Index/BFS.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
| [589. N 叉树的前序遍历](https://leetcode-cn.com/problems/n-ary-tree-preorder-traversal/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/n-ary-tree-preorder-traversal/solution/gong-shui-san-xie-shu-de-sou-suo-yun-yon-pse1/) | 简单 | 🤩🤩🤩 |
| [590. N 叉树的后序遍历](https://leetcode-cn.com/problems/n-ary-tree-postorder-traversal/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/n-ary-tree-postorder-traversal/solution/by-ac_oier-ul7t/) | 简单 | 🤩🤩🤩 |
| [623. 在二叉树中增加一行](https://leetcode.cn/problems/add-one-row-to-tree/) | [LeetCode 题解链接](https://leetcode.cn/problems/add-one-row-to-tree/solution/by-ac_oier-sc34/) | 中等 | 🤩🤩🤩🤩 |
| [669. 修剪二叉搜索树](https://leetcode.cn/problems/trim-a-binary-search-tree/) | [LeetCode 题解链接](https://leetcode.cn/problems/trim-a-binary-search-tree/solution/by-ac_oier-help/) | 中等 | 🤩🤩🤩🤩 |
| [690. 员工的重要性](https://leetcode-cn.com/problems/employee-importance/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/employee-importance/solution/gong-shui-san-xie-yi-ti-shuang-jie-di-gu-s79x/) | 简单 | 🤩🤩🤩 |
| [778. 水位上升的泳池中游泳](https://leetcode-cn.com/problems/swim-in-rising-water/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/swim-in-rising-water/solution/gong-shui-san-xie-yi-ti-shuang-jie-krusk-7c6o/) | 困难 | 🤩🤩🤩 |
| [783. 二叉搜索树节点最小距离](https://leetcode-cn.com/problems/minimum-distance-between-bst-nodes/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/minimum-distance-between-bst-nodes/solution/gong-shui-san-xie-yi-ti-san-jie-shu-de-s-7r17/) | 简单 | 🤩🤩🤩 |
Expand Down
1 change: 1 addition & 0 deletions Index/DFS.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
| [654. 最大二叉树](https://leetcode.cn/problems/maximum-binary-tree/) | [LeetCode 题解链接](https://leetcode.cn/problems/maximum-binary-tree/solution/by-ac_oier-s0wc/) | 中等 | 🤩🤩🤩🤩🤩 |
| [655. 输出二叉树](https://leetcode.cn/problems/print-binary-tree/) | [LeetCode 题解链接](https://leetcode.cn/problems/print-binary-tree/solution/by-ac_oier-mays/) | 中等 | 🤩🤩🤩🤩 |
| [662. 二叉树最大宽度](https://leetcode.cn/problems/maximum-width-of-binary-tree/) | [LeetCode 题解链接](https://leetcode.cn/problems/maximum-width-of-binary-tree/solution/by-ac_oier-33er/) | 中等 | 🤩🤩🤩🤩 |
| [669. 修剪二叉搜索树](https://leetcode.cn/problems/trim-a-binary-search-tree/) | [LeetCode 题解链接](https://leetcode.cn/problems/trim-a-binary-search-tree/solution/by-ac_oier-help/) | 中等 | 🤩🤩🤩🤩 |
| [676. 实现一个魔法字典](https://leetcode.cn/problems/implement-magic-dictionary/) | [LeetCode 题解链接](https://leetcode.cn/problems/implement-magic-dictionary/solution/by-ac_oier-a01l/) | 中等 | 🤩🤩🤩🤩🤩 |
| [677. 键值映射](https://leetcode-cn.com/problems/map-sum-pairs/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/map-sum-pairs/solution/gong-shui-san-xie-jie-he-dfs-de-trie-yun-i4xa/) | 中等 | 🤩🤩🤩🤩 |
| [687. 最长同值路径](https://leetcode.cn/problems/longest-univalue-path/) | [LeetCode 题解链接](https://leetcode.cn/problems/longest-univalue-path/solution/by-ac_oier-8ue8/) | 中等 | 🤩🤩🤩🤩 |
Expand Down
1 change: 1 addition & 0 deletions Index/二叉树.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
| [654. 最大二叉树](https://leetcode.cn/problems/maximum-binary-tree/) | [LeetCode 题解链接](https://leetcode.cn/problems/maximum-binary-tree/solution/by-ac_oier-s0wc/) | 中等 | 🤩🤩🤩🤩🤩 |
| [655. 输出二叉树](https://leetcode.cn/problems/print-binary-tree/) | [LeetCode 题解链接](https://leetcode.cn/problems/print-binary-tree/solution/by-ac_oier-mays/) | 中等 | 🤩🤩🤩🤩 |
| [662. 二叉树最大宽度](https://leetcode.cn/problems/maximum-width-of-binary-tree/) | [LeetCode 题解链接](https://leetcode.cn/problems/maximum-width-of-binary-tree/solution/by-ac_oier-33er/) | 中等 | 🤩🤩🤩🤩🤩 |
| [669. 修剪二叉搜索树](https://leetcode.cn/problems/trim-a-binary-search-tree/) | [LeetCode 题解链接](https://leetcode.cn/problems/trim-a-binary-search-tree/solution/by-ac_oier-help/) | 中等 | 🤩🤩🤩🤩 |
| [687. 最长同值路径](https://leetcode.cn/problems/longest-univalue-path/) | [LeetCode 题解链接](https://leetcode.cn/problems/longest-univalue-path/solution/by-ac_oier-8ue8/) | 中等 | 🤩🤩🤩🤩 |
| [783. 二叉搜索树节点最小距离](https://leetcode-cn.com/problems/minimum-distance-between-bst-nodes/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/minimum-distance-between-bst-nodes/solution/gong-shui-san-xie-yi-ti-san-jie-shu-de-s-7r17/) | 简单 | 🤩🤩🤩 |
| [814. 二叉树剪枝](https://leetcode.cn/problems/binary-tree-pruning/) | [LeetCode 题解链接](https://leetcode.cn/problems/binary-tree-pruning/solution/by-ac_oier-7me9/) | 中等 | 🤩🤩🤩🤩🤩 |
Expand Down
132 changes: 132 additions & 0 deletions LeetCode/661-670/669. 修剪二叉搜索树(中等).md
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
### 题目描述

这是 LeetCode 上的 **[669. 修剪二叉搜索树](https://leetcode.cn/problems/trim-a-binary-search-tree/solution/by-ac_oier-help/)** ,难度为 **中等**。

Tag : 「BST」、「二叉树」、「递归」、「迭代」



给你二叉搜索树的根节点 `root`,同时给定最小边界 `low` 和最大边界 `high`。通过修剪二叉搜索树,使得所有节点的值在 $[low, high]$ 中。修剪树 不应该 改变保留在树中的元素的相对结构 (即,如果没有被移除,原有的父代子代关系都应当保留)。 可以证明,存在 唯一的答案 。

所以结果应当返回修剪好的二叉搜索树的新的根节点。注意,根节点可能会根据给定的边界发生改变。

示例 1:
![](https://assets.leetcode.com/uploads/2020/09/09/trim1.jpg)
```
输入:root = [1,0,2], low = 1, high = 2

输出:[1,null,2]
```
示例 2:
![](https://assets.leetcode.com/uploads/2020/09/09/trim2.jpg)
```
输入:root = [3,0,4,null,2,null,null,1], low = 1, high = 3

输出:[3,2,null,1]
```

提示:
* 树中节点数在范围 $[1, 10^4]$ 内
* $0 <= Node.val <= 10^4$
* 树中每个节点的值都是 唯一 的
* 题目数据保证输入是一棵有效的二叉搜索树
* $0 <= low <= high <= 10^4$

---

### 递归

由于被修剪的是二叉搜索树,因此修剪过程必然能够顺利进行。

容易想到使用原函数作为递归函数:

* 若 `root.val` 小于边界值 `low`,则 `root` 的左子树必然均小于边界值,我们递归处理 `root.right` 即可;
* 若 `root.val` 大于边界值 `high`,则 `root` 的右子树必然均大于边界值,我们递归处理 `root.left` 即可;
* 若 `root.val` 符合要求,则 `root` 可被保留,递归处理其左右节点并重新赋值即可。

Java 代码:
```Java
class Solution {
public TreeNode trimBST(TreeNode root, int low, int high) {
if (root == null) return null;
if (root.val < low) return trimBST(root.right, low, high);
else if (root.val > high) return trimBST(root.left, low, high);
root.left = trimBST(root.left, low, high);
root.right = trimBST(root.right, low, high);
return root;
}
}
```
TypeScript 代码:
```TypeScript
function trimBST(root: TreeNode | null, low: number, high: number): TreeNode | null {
if (root == null) return null
if (root.val < low) return trimBST(root.right, low, high)
else if (root.val > high) return trimBST(root.left, low, high)
root.left = trimBST(root.left, low, high)
root.right = trimBST(root.right, low, high)
return root
};
```
* 时间复杂度:$O(n)$
* 空间复杂度:忽略递归带来的额外空间开销,复杂度为 $O(1)$

---

### 迭代

自然能够使用「迭代」进行求解:起始先从给定的 `root` 进行出发,找到第一个满足值符合 $[low, high]$ 范围的节点,该节点为最后要返回的根节点 `ans`。

随后考虑如何修剪 `ans` 的左右节点:当根节点符合 $[low, high]$ 要求时,修剪左右节点过程中仅需考虑一边的边界值即可。即对于 `ans.left` 只需考虑将值小于 `low` 的节点去掉(因为二叉搜索树的特性,`ans` 满足不大于 `high` 要求,则其左节点必然满足);同理 `ans.right` 只需要考虑将大于 `high` 的节点去掉即可。

Java 代码:
```Java
class Solution {
public TreeNode trimBST(TreeNode root, int low, int high) {
while (root != null && (root.val < low || root.val > high)) root = root.val < low ? root.right : root.left;
TreeNode ans = root;
while (root != null) {
while (root.left != null && root.left.val < low) root.left = root.left.right;
root = root.left;
}
root = ans;
while (root != null) {
while (root.right != null && root.right.val > high) root.right = root.right.left;
root = root.right;
}
return ans;
}
}
```
TypeScript 代码:
```TypeScript
function trimBST(root: TreeNode | null, low: number, high: number): TreeNode | null {
while (root != null && (root.val < low || root.val > high)) root = root.val < low ? root.right : root.left
const ans = root
while (root != null) {
while (root.left != null && root.left.val < low) root.left = root.left.right
root = root.left
}
root = ans
while (root != null) {
while (root.right != null && root.right.val > high) root.right = root.right.left
root = root.right
}
return ans
};
```
* 时间复杂度:$O(n)$
* 空间复杂度:$O(1)$

---

### 最后

这是我们「刷穿 LeetCode」系列文章的第 `No.669` 篇,系列开始于 2021/01/01,截止于起始日 LeetCode 上共有 1916 道题目,部分是有锁题,我们将先把所有不带锁的题目刷完。

在这个系列文章里面,除了讲解解题思路以外,还会尽可能给出最为简洁的代码。如果涉及通解还会相应的代码模板。

为了方便各位同学能够电脑上进行调试和提交代码,我建立了相关的仓库:https://github.com/SharingSource/LogicStack-LeetCode 。

在仓库地址里,你可以看到系列文章的题解链接、系列文章的相应代码、LeetCode 原题链接和其他优选题解。